Index: src/main/groovy/lang/MetaClass.java =================================================================== RCS file: /scm/cvspublic/groovy/groovy-core/src/main/groovy/lang/MetaClass.java,v retrieving revision 1.70 diff -u -r1.70 MetaClass.java --- src/main/groovy/lang/MetaClass.java 19 Apr 2004 07:29:42 -0000 1.70 +++ src/main/groovy/lang/MetaClass.java 24 Apr 2004 22:36:36 -0000 @@ -58,6 +58,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; +import java.math.BigDecimal; import java.net.URL; import java.security.AccessControlException; import java.security.AccessController; @@ -1355,7 +1356,7 @@ return value instanceof Integer; } else if (type == double.class) { - return value instanceof Double || value instanceof Float || value instanceof Integer; + return value instanceof Double || value instanceof Float || value instanceof Integer || value instanceof BigDecimal; } else if (type == boolean.class) { return value instanceof Boolean; Index: src/main/org/codehaus/groovy/runtime/Invoker.java =================================================================== RCS file: /scm/cvspublic/groovy/groovy-core/src/main/org/codehaus/groovy/runtime/Invoker.java,v retrieving revision 1.54 diff -u -r1.54 Invoker.java --- src/main/org/codehaus/groovy/runtime/Invoker.java 6 Mar 2004 15:52:00 -0000 1.54 +++ src/main/org/codehaus/groovy/runtime/Invoker.java 24 Apr 2004 22:36:38 -0000 @@ -687,7 +687,14 @@ return new Float(n.floatValue()); } if (type == double.class) { - return new Double(n.doubleValue()); + Double answer = new Double(n.doubleValue()); + //throw a runtime exception if conversion would be out-of-range for the type. + if (!(n instanceof Double) && (answer.doubleValue() == Double.NEGATIVE_INFINITY + || answer.doubleValue() == Double.POSITIVE_INFINITY)) { + throw new GroovyRuntimeException("Automatic coercion of "+n.getClass().getName() + +" value "+n+" to double failed. Value is out of range."); + } + return answer; } } else { @@ -711,7 +718,14 @@ return new Float(n.floatValue()); } if (type == Double.class) { - return new Double(n.doubleValue()); + Double answer = new Double(n.doubleValue()); + //throw a runtime exception if conversion would be out-of-range for the type. + if (!(n instanceof Double) && (answer.doubleValue() == Double.NEGATIVE_INFINITY + || answer.doubleValue() == Double.POSITIVE_INFINITY)) { + throw new GroovyRuntimeException("Automatic coercion of "+n.getClass().getName() + +" value "+n+" to double failed. Value is out of range."); + } + return answer; } } Index: src/test/groovy/DoubleOperationTest.groovy =================================================================== RCS file: /scm/cvspublic/groovy/groovy-core/src/test/groovy/DoubleOperationTest.groovy,v retrieving revision 1.7 diff -u -r1.7 DoubleOperationTest.groovy --- src/test/groovy/DoubleOperationTest.groovy 15 Nov 2003 05:42:09 -0000 1.7 +++ src/test/groovy/DoubleOperationTest.groovy 24 Apr 2004 22:36:41 -0000 @@ -54,4 +54,19 @@ y = x / 2 assert y == 10.0 : "y = " + y } + + void testCoerce() { + xyz = Math.sin(1.1); + assert xyz instanceof Double; + assert xyz == Math.sin(1.1D); + + //Note that (7.3F).doubleValue() != 7.3D + x = Math.sin(7.3F); + assert x instanceof Double; + assert x == Math.sin((7.3F).doubleValue()); + + x = Math.sin(7); + assert x instanceof Double; + assert x == Math.sin(7.0D); + } } Index: src/test/org/codehaus/groovy/runtime/InvokeMethodTest.java =================================================================== RCS file: /scm/cvspublic/groovy/groovy-core/src/test/org/codehaus/groovy/runtime/InvokeMethodTest.java,v retrieving revision 1.26 diff -u -r1.26 InvokeMethodTest.java --- src/test/org/codehaus/groovy/runtime/InvokeMethodTest.java 10 Mar 2004 16:41:20 -0000 1.26 +++ src/test/org/codehaus/groovy/runtime/InvokeMethodTest.java 24 Apr 2004 22:36:47 -0000 @@ -40,6 +40,7 @@ import groovy.lang.IntRange; import groovy.util.GroovyTestCase; +import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; @@ -261,6 +262,17 @@ }; Object value = invoke("test", "getBytes", new Object[] { param }); assertEquals("converted GString to string", "test".getBytes("US-ASCII").getClass(), value.getClass()); + } + + public void testBadBDToDoubleCoerce() throws Throwable { + try { + Object value = invoke(Math.class, "floor", new BigDecimal("1.7E309")); + } catch (GroovyRuntimeException e) { + assertTrue("Math.floor(1.7E309) should fail because it is out of range for a Double. " + +e,e.getMessage().indexOf("out of range") > 0); + return; + } + fail("Math.floor(1.7E309) should fail because it is out of range for a Double."); } public void testClassMethod() throws Throwable {