From d6c7e3e6a70c01ca45107f29b1f5096838eed1ae Mon Sep 17 00:00:00 2001 From: Javen O'Neal Date: Thu, 13 Jul 2017 03:35:06 +0000 Subject: [PATCH] github #43: fix roundUp and roundDown. 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 --- .../poi/ss/formula/functions/MathX.java | 28 +++++-------------- .../poi/ss/formula/functions/TestMathX.java | 11 +++++--- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/src/java/org/apache/poi/ss/formula/functions/MathX.java b/src/java/org/apache/poi/ss/formula/functions/MathX.java index 710e611081..cf36440375 100644 --- a/src/java/org/apache/poi/ss/formula/functions/MathX.java +++ b/src/java/org/apache/poi/ss/formula/functions/MathX.java @@ -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; diff --git a/src/testcases/org/apache/poi/ss/formula/functions/TestMathX.java b/src/testcases/org/apache/poi/ss/formula/functions/TestMathX.java index 12c8425546..fab40b709c 100644 --- a/src/testcases/org/apache/poi/ss/formula/functions/TestMathX.java +++ b/src/testcases/org/apache/poi/ss/formula/functions/TestMathX.java @@ -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() { -- 2.39.5