From: PJ Fanning Date: Fri, 29 Apr 2022 12:25:29 +0000 (+0000) Subject: [bug-66047] change mround implementation due to issue - thanks to @fabio X-Git-Tag: REL_5_2_3~346 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=88441c4354010c1c1f7f9054c63c56211fb61aee;p=poi.git [bug-66047] change mround implementation due to issue - thanks to @fabio git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1900376 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/poi/src/main/java/org/apache/poi/ss/formula/atp/MRound.java b/poi/src/main/java/org/apache/poi/ss/formula/atp/MRound.java index 1068f974b7..7d24b90892 100644 --- a/poi/src/main/java/org/apache/poi/ss/formula/atp/MRound.java +++ b/poi/src/main/java/org/apache/poi/ss/formula/atp/MRound.java @@ -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()
* @@ -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); diff --git a/poi/src/test/java/org/apache/poi/ss/formula/atp/TestMRound.java b/poi/src/test/java/org/apache/poi/ss/formula/atp/TestMRound.java index 493ac8a9d8..9df86af58a 100644 --- a/poi/src/test/java/org/apache/poi/ss/formula/atp/TestMRound.java +++ b/poi/src/test/java/org/apache/poi/ss/formula/atp/TestMRound.java @@ -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)"); } }