You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2020/12/03 13:14:09 UTC

[groovy] branch GROOVY_3_0_X updated: Minor tweak for `BigDecimal` and `BigInteger`

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
     new 92dc8c8  Minor tweak for `BigDecimal` and `BigInteger`
92dc8c8 is described below

commit 92dc8c8d06e82059339c0daa8305c2b297ffa0ab
Author: Daniel Sun <su...@apache.org>
AuthorDate: Thu Dec 3 21:13:11 2020 +0800

    Minor tweak for `BigDecimal` and `BigInteger`
---
 src/main/java/groovy/lang/NumberRange.java         | 13 +++++----
 src/main/java/groovy/lang/ObjectRange.java         |  5 ++--
 .../stdclasses/BigDecimalCachedClass.java          | 12 ++------
 .../groovy/runtime/DefaultGroovyMethods.java       | 33 +++++-----------------
 .../typehandling/DefaultTypeTransformation.java    | 14 ++-------
 .../groovy/runtime/typehandling/NumberMath.java    |  8 +++++-
 6 files changed, 28 insertions(+), 57 deletions(-)

diff --git a/src/main/java/groovy/lang/NumberRange.java b/src/main/java/groovy/lang/NumberRange.java
index a58dd1b..11f2ab3 100644
--- a/src/main/java/groovy/lang/NumberRange.java
+++ b/src/main/java/groovy/lang/NumberRange.java
@@ -21,6 +21,7 @@ package groovy.lang;
 import org.codehaus.groovy.runtime.InvokerHelper;
 import org.codehaus.groovy.runtime.IteratorClosureAdapter;
 import org.codehaus.groovy.runtime.RangeInfo;
+import org.codehaus.groovy.runtime.typehandling.NumberMath;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
@@ -418,16 +419,16 @@ public class NumberRange extends AbstractList<Comparable> implements Range<Compa
                 final BigInteger fromNum = new BigInteger(from.toString());
                 final BigInteger toTemp = new BigInteger(to.toString());
                 final BigInteger toNum = inclusive ? toTemp : toTemp.subtract(BigInteger.ONE);
-                final BigInteger sizeNum = new BigDecimal(toNum.subtract(fromNum)).divide(new BigDecimal(stepSize.longValue()), RoundingMode.DOWN).toBigInteger().add(BigInteger.ONE);
+                final BigInteger sizeNum = new BigDecimal(toNum.subtract(fromNum)).divide(BigDecimal.valueOf(stepSize.longValue()), RoundingMode.DOWN).toBigInteger().add(BigInteger.ONE);
                 tempsize = sizeNum.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) < 0 ? sizeNum.intValue() : Integer.MAX_VALUE;
                 shortcut = true;
             } else if (((from instanceof BigDecimal || from instanceof BigInteger) && to instanceof Number) ||
                     ((to instanceof BigDecimal || to instanceof BigInteger) && from instanceof Number)) {
                 // let's fast calculate the size
-                final BigDecimal fromNum = new BigDecimal(from.toString());
-                final BigDecimal toTemp = new BigDecimal(to.toString());
-                final BigDecimal toNum = inclusive ? toTemp : toTemp.subtract(new BigDecimal("1.0"));
-                final BigInteger sizeNum = toNum.subtract(fromNum).divide(new BigDecimal(stepSize.longValue()), RoundingMode.DOWN).toBigInteger().add(BigInteger.ONE);
+                final BigDecimal fromNum = NumberMath.toBigDecimal((Number) from);
+                final BigDecimal toTemp = NumberMath.toBigDecimal((Number) to);
+                final BigDecimal toNum = inclusive ? toTemp : toTemp.subtract(BigDecimal.ONE);
+                final BigInteger sizeNum = toNum.subtract(fromNum).divide(BigDecimal.valueOf(stepSize.longValue()), RoundingMode.DOWN).toBigInteger().add(BigInteger.ONE);
                 tempsize = sizeNum.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) < 0 ? sizeNum.intValue() : Integer.MAX_VALUE;
                 shortcut = true;
             }
@@ -452,7 +453,7 @@ public class NumberRange extends AbstractList<Comparable> implements Range<Compa
     }
 
     private boolean isIntegral(Number stepSize) {
-        BigDecimal tempStepSize = new BigDecimal(stepSize.toString());
+        BigDecimal tempStepSize = NumberMath.toBigDecimal(stepSize);
         return tempStepSize.equals(new BigDecimal(tempStepSize.toBigInteger()));
     }
 
diff --git a/src/main/java/groovy/lang/ObjectRange.java b/src/main/java/groovy/lang/ObjectRange.java
index 19c585e..dbf9707 100644
--- a/src/main/java/groovy/lang/ObjectRange.java
+++ b/src/main/java/groovy/lang/ObjectRange.java
@@ -23,6 +23,7 @@ import org.codehaus.groovy.runtime.InvokerHelper;
 import org.codehaus.groovy.runtime.IteratorClosureAdapter;
 import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
 import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
+import org.codehaus.groovy.runtime.typehandling.NumberMath;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -300,8 +301,8 @@ public class ObjectRange extends AbstractList<Comparable> implements Range<Compa
             } else if (((from instanceof BigDecimal || from instanceof BigInteger) && to instanceof Number) ||
                     ((to instanceof BigDecimal || to instanceof BigInteger) && from instanceof Number)) {
                 // let's fast calculate the size
-                final BigDecimal fromNum = new BigDecimal(from.toString());
-                final BigDecimal toNum = new BigDecimal(to.toString());
+                final BigDecimal fromNum = NumberMath.toBigDecimal((Number) from);
+                final BigDecimal toNum = NumberMath.toBigDecimal((Number) to);
                 final BigInteger sizeNum = toNum.subtract(fromNum).add(BigDecimal.ONE).toBigInteger();
                 tempsize = sizeNum.intValue();
                 if (!BigInteger.valueOf(tempsize).equals(sizeNum)) {
diff --git a/src/main/java/org/codehaus/groovy/reflection/stdclasses/BigDecimalCachedClass.java b/src/main/java/org/codehaus/groovy/reflection/stdclasses/BigDecimalCachedClass.java
index d1f7646..2a20786 100644
--- a/src/main/java/org/codehaus/groovy/reflection/stdclasses/BigDecimalCachedClass.java
+++ b/src/main/java/org/codehaus/groovy/reflection/stdclasses/BigDecimalCachedClass.java
@@ -19,9 +19,9 @@
 package org.codehaus.groovy.reflection.stdclasses;
 
 import org.codehaus.groovy.reflection.ClassInfo;
+import org.codehaus.groovy.runtime.typehandling.NumberMath;
 
 import java.math.BigDecimal;
-import java.math.BigInteger;
 
 public class BigDecimalCachedClass extends DoubleCachedClass {
     public BigDecimalCachedClass(Class klazz, ClassInfo classInfo) {
@@ -33,16 +33,8 @@ public class BigDecimalCachedClass extends DoubleCachedClass {
     }
 
     public Object coerceArgument(Object argument) {
-        if (argument instanceof BigDecimal) {
-            return argument;
-        } else if (argument instanceof Long) {
-            return new BigDecimal((Long) argument);
-        } else if (argument instanceof BigInteger) {
-            return new BigDecimal((BigInteger) argument);
-        }
-
         if (argument instanceof Number) {
-            return new BigDecimal(((Number) argument).doubleValue());
+            return NumberMath.toBigDecimal((Number) argument);
         }
         return argument;
     }
diff --git a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
index 252a7fd..5bda5d9 100644
--- a/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java
@@ -16284,7 +16284,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
                 throw new GroovyRuntimeException("The argument (" + to +
                         ") to upto() cannot be less than the value (" + self + ") it's called on.");
         } else {
-            BigDecimal to1 = new BigDecimal(to.toString());
+            BigDecimal to1 = NumberMath.toBigDecimal(to);
             if (self.compareTo(to1) <= 0) {
                 for (BigDecimal i = self; i.compareTo(to1) <= 0; i = i.add(one)) {
                     closure.call(i);
@@ -16516,7 +16516,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
             } else
                 throw new GroovyRuntimeException("The argument (" + to +
                         ") to downto() cannot be greater than the value (" + self + ") it's called on.");        } else {
-            BigDecimal to1 = new BigDecimal(to.toString());
+            BigDecimal to1 = NumberMath.toBigDecimal(to);
             if (self.compareTo(to1) >= 0) {
                 for (BigDecimal i = self; i.compareTo(to1) >= 0; i = i.subtract(one)) {
                     closure.call(i);
@@ -16545,9 +16545,9 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
     public static void step(Number self, Number to, Number stepNumber, Closure closure) {
         if (self instanceof BigDecimal || to instanceof BigDecimal || stepNumber instanceof BigDecimal) {
             final BigDecimal zero = BigDecimal.valueOf(0, 1);  // Same as "0.0".
-            BigDecimal self1 = (self instanceof BigDecimal) ? (BigDecimal) self : new BigDecimal(self.toString());
-            BigDecimal to1 = (to instanceof BigDecimal) ? (BigDecimal) to : new BigDecimal(to.toString());
-            BigDecimal stepNumber1 = (stepNumber instanceof BigDecimal) ? (BigDecimal) stepNumber : new BigDecimal(stepNumber.toString());
+            BigDecimal self1 = NumberMath.toBigDecimal(self);
+            BigDecimal to1 = NumberMath.toBigDecimal(to);
+            BigDecimal stepNumber1 = NumberMath.toBigDecimal(stepNumber);
             if (stepNumber1.compareTo(zero) > 0 && to1.compareTo(self1) > 0) {
                 for (BigDecimal i = self1; i.compareTo(to1) < 0; i = i.add(stepNumber1)) {
                     closure.call(i);
@@ -16981,16 +16981,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 1.0
      */
     public static BigDecimal toBigDecimal(Number self) {
-        // Quick method for scalars.
-        if ((self instanceof Long)
-                || (self instanceof Integer)
-                || (self instanceof Short)
-                || (self instanceof Byte))
-        {
-            return BigDecimal.valueOf(self.longValue());
-        }
-
-        return new BigDecimal(self.toString());
+        return NumberMath.toBigDecimal(self);
     }
 
     /**
@@ -17030,17 +17021,7 @@ public class DefaultGroovyMethods extends DefaultGroovyMethodsSupport {
      * @since 1.0
      */
     public static BigInteger toBigInteger(Number self) {
-        if (self instanceof BigInteger) {
-            return (BigInteger) self;
-        } else if (self instanceof BigDecimal) {
-            return ((BigDecimal) self).toBigInteger();
-        } else if (self instanceof Double) {
-            return new BigDecimal((Double)self).toBigInteger();
-        } else if (self instanceof Float) {
-            return new BigDecimal((Float)self).toBigInteger();
-        } else {
-            return new BigInteger(Long.toString(self.longValue()));
-        }
+        return NumberMath.toBigInteger(self);
     }
 
     // Boolean based methods
diff --git a/src/main/java/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java b/src/main/java/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java
index d2e72c2..ec42a9d 100644
--- a/src/main/java/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java
+++ b/src/main/java/org/codehaus/groovy/runtime/typehandling/DefaultTypeTransformation.java
@@ -309,20 +309,10 @@ public class DefaultTypeTransformation {
                 return answer;
             }
             if (type == BigDecimal.class) {
-                if (n instanceof Float || n instanceof Double) {
-                    return new BigDecimal(n.doubleValue());
-                }
-                return new BigDecimal(n.toString());
+                return NumberMath.toBigDecimal(n);
             }
             if (type == BigInteger.class) {
-                if (object instanceof Float || object instanceof Double) {
-                    BigDecimal bd = new BigDecimal(n.doubleValue());
-                    return bd.toBigInteger();
-                }
-                if (object instanceof BigDecimal) {
-                    return ((BigDecimal) object).toBigInteger();
-                }
-                return new BigInteger(n.toString());
+                return NumberMath.toBigInteger(n);
             }
         }
 
diff --git a/src/main/java/org/codehaus/groovy/runtime/typehandling/NumberMath.java b/src/main/java/org/codehaus/groovy/runtime/typehandling/NumberMath.java
index 299c524..9ee014d 100644
--- a/src/main/java/org/codehaus/groovy/runtime/typehandling/NumberMath.java
+++ b/src/main/java/org/codehaus/groovy/runtime/typehandling/NumberMath.java
@@ -187,9 +187,15 @@ public abstract class NumberMath {
         if (n instanceof Integer || n instanceof Long || n instanceof Byte || n instanceof Short) {
             return BigInteger.valueOf(n.longValue());
         }
+
+        if (n instanceof Float || n instanceof Double) {
+            BigDecimal bd = new BigDecimal(n.toString());
+            return bd.toBigInteger();
+        }
         if (n instanceof BigDecimal) {
-            return ((BigDecimal) n).toBigIntegerExact();
+            return ((BigDecimal) n).toBigInteger();
         }
+
         return new BigInteger(n.toString());
     }