]> source.dussan.org Git - poi.git/commitdiff
[bug-66047] change mround implementation due to issue - thanks to @fabio
authorPJ Fanning <fanningpj@apache.org>
Fri, 29 Apr 2022 12:25:29 +0000 (12:25 +0000)
committerPJ Fanning <fanningpj@apache.org>
Fri, 29 Apr 2022 12:25:29 +0000 (12:25 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1900376 13f79535-47bb-0310-9956-ffa450edef68

poi/src/main/java/org/apache/poi/ss/formula/atp/MRound.java
poi/src/test/java/org/apache/poi/ss/formula/atp/TestMRound.java

index 1068f974b7e2ff1dfff9995f699d99c4d9ca129b..7d24b908921ae5cb284da4f76d95da88c46a54b4 100644 (file)
@@ -22,6 +22,9 @@ import org.apache.poi.ss.formula.eval.*;
 import org.apache.poi.ss.formula.functions.FreeRefFunction;
 import org.apache.poi.ss.formula.functions.NumericFunction;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
 /**
  * Implementation of Excel 'Analysis ToolPak' function MROUND()<br>
  *
@@ -56,7 +59,10 @@ final class MRound implements FreeRefFunction {
                     // Returns #NUM! because the number and the multiple have different signs
                     throw new EvaluationException(ErrorEval.NUM_ERROR);
                 }
-                result = multiple * Math.round( number / multiple );
+                BigDecimal bdMultiple = BigDecimal.valueOf(multiple);
+                result = bdMultiple.multiply(BigDecimal.valueOf(number).divide(bdMultiple, 0, RoundingMode.HALF_UP))
+                        .doubleValue();
+
             }
             NumericFunction.checkValue(result);
             return new NumberEval(result);
index 493ac8a9d8f8ba7b1874e8ff6d255619efc68c7a..9df86af58af9ae9254ce5831ce4177cb703806ac 100644 (file)
@@ -31,6 +31,7 @@ import org.junit.jupiter.api.Test;
  */
 class TestMRound {
 
+    //examples from https://support.microsoft.com/en-us/office/mround-function-c299c3b0-15a5-426d-aa4b-d2d5b3baf427
     /**
         =MROUND(10, 3)  Rounds 10 to a nearest multiple of 3 (9)
         =MROUND(-10, -3)    Rounds -10 to a nearest multiple of -3 (-9)
@@ -51,6 +52,8 @@ class TestMRound {
         cell4.setCellFormula("MROUND(5, -2)");
         Cell cell5 = sh.createRow(0).createCell(0);
         cell5.setCellFormula("MROUND(5, 0)");
+        Cell cell6 = sh.createRow(0).createCell(0);
+        cell6.setCellFormula("MROUND(0.79*7.5, 0.05)");
 
         double accuracy = 1E-9;
 
@@ -70,5 +73,8 @@ class TestMRound {
 
         assertEquals(0.0, evaluator.evaluate(cell5).getNumberValue(), 0,
                      "Returns 0 because the multiple is 0");
+
+        assertEquals(5.95, evaluator.evaluate(cell6).getNumberValue(), 0,
+                "Rounds 5.925 to a nearest multiple of 0.05 (5.95)");
     }
 }