]> source.dussan.org Git - poi.git/commitdiff
github #43: fix roundUp and roundDown.
authorJaven O'Neal <onealj@apache.org>
Thu, 13 Jul 2017 03:35:06 +0000 (03:35 +0000)
committerJaven O'Neal <onealj@apache.org>
Thu, 13 Jul 2017 03:35:06 +0000 (03:35 +0000)
Thanks to @FishMeat on github for the patch.
This closes #43 on github.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1801798 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/ss/formula/functions/MathX.java
src/testcases/org/apache/poi/ss/formula/functions/TestMathX.java

index 710e61108176b8275f458fa92a33581653111879..cf36440375ed6dc020add11831b5ec0acc27d86d 100644 (file)
@@ -48,16 +48,7 @@ final class MathX {
      * @param p
      */
     public static double round(double n, int p) {
-        double retval;
-
-        if (Double.isNaN(n) || Double.isInfinite(n)) {
-            retval = Double.NaN;
-        }
-        else {
-            retval = new java.math.BigDecimal(NumberToTextConverter.toText(n)).setScale(p, java.math.RoundingMode.HALF_UP).doubleValue();
-        }
-
-        return retval;
+        return round(n, p, java.math.RoundingMode.HALF_UP);
     }
 
     /**
@@ -76,16 +67,7 @@ final class MathX {
      * @param p
      */
     public static double roundUp(double n, int p) {
-        double retval;
-
-        if (Double.isNaN(n) || Double.isInfinite(n)) {
-            retval = Double.NaN;
-        }
-        else {
-            retval = java.math.BigDecimal.valueOf(n).setScale(p, java.math.RoundingMode.UP).doubleValue();
-        }
-
-        return retval;
+        return round(n, p, java.math.RoundingMode.UP);
     }
 
     /**
@@ -104,13 +86,17 @@ final class MathX {
      * @param p
      */
     public static double roundDown(double n, int p) {
+        return round(n, p, java.math.RoundingMode.DOWN);
+    }
+    
+    private static double round(double n, int p, java.math.RoundingMode rounding) {
         double retval;
 
         if (Double.isNaN(n) || Double.isInfinite(n)) {
             retval = Double.NaN;
         }
         else {
-            retval = java.math.BigDecimal.valueOf(n).setScale(p, java.math.RoundingMode.DOWN).doubleValue();
+            retval = new java.math.BigDecimal(NumberToTextConverter.toText(n)).setScale(p, rounding).doubleValue();
         }
 
         return retval;
index 12c8425546863f27633f90c87dadcb264ab4bb36..fab40b709cbedd27a5d18e4230ba8d92db02eee7 100644 (file)
@@ -750,7 +750,7 @@ public class TestMathX extends AbstractNumericTestCase {
         d = 150.0; p = -2;
         assertEquals("roundDown ", 100, MathX.roundDown(d, p));
         
-        d = 0.049999999999999975d; p = 2;
+        d = 0.0499999999999975d; p = 2;
         assertEquals("roundDown ", 0.04d, MathX.roundDown(d, p));
 
         d = 0.049999999999999975d; p = 1;
@@ -839,13 +839,16 @@ public class TestMathX extends AbstractNumericTestCase {
         d = Double.MAX_VALUE; p = 1;
         assertEquals("roundUp ", Double.MAX_VALUE, MathX.roundUp(d, p));
 
+        // Excel's min positive value is several orders of magnitude larger than Java's (Java 8: 4.9e-324, Excel 2016 on Windows 10: 2.2259157957E-308)
         d = Double.MIN_VALUE; p = 1;
+        assertEquals("roundUp ", 0.0d, MathX.roundUp(d, p));
+        d = 2.2259157957E-308; p = 1;
         assertEquals("roundUp ", 0.1d, MathX.roundUp(d, p));
 
         //github-43: https://github.com/apache/poi/pull/43
-        //@Ignore("ROUNDUP(3987*0.2, 2) currently fails by returning 797.41")
-        //d = 3987 * 0.2; p = 2;
-        //assertEquals("roundUp ", 797.40, MathX.roundUp(d, p));
+        // "ROUNDUP(3987*0.2, 2) currently fails by returning 797.41")
+        d = 3987 * 0.2; p = 2;
+        assertEquals("roundUp ", 797.40, MathX.roundUp(d, p));
     }
 
     public void testCeiling() {