Bug 51339 - Fixed arithmetic rounding in formula evaluation

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1135079 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2011-06-13 10:34:43 +00:00
parent d2c43ea1ab
commit 8b2603f7f6
4 changed files with 26 additions and 30 deletions

View File

@ -34,6 +34,7 @@
<changes> <changes>
<release version="3.8-beta4" date="2011-??-??"> <release version="3.8-beta4" date="2011-??-??">
<action dev="poi-developers" type="add">51339 - Fixed arithmetic rounding in formula evaluation </action>
<action dev="poi-developers" type="add">51356 - Support autoSizeColumn in SXSSF</action> <action dev="poi-developers" type="add">51356 - Support autoSizeColumn in SXSSF</action>
<action dev="poi-developers" type="add">51335 - Parse picture goal and crop sizes in HWPF</action> <action dev="poi-developers" type="add">51335 - Parse picture goal and crop sizes in HWPF</action>
<action dev="poi-developers" type="add">51305 - Add sprmTCellPaddingDefault support in HWPF</action> <action dev="poi-developers" type="add">51305 - Add sprmTCellPaddingDefault support in HWPF</action>

View File

@ -53,13 +53,7 @@ final class MathX {
retval = Double.NaN; retval = Double.NaN;
} }
else { else {
if (p != 0) { retval = java.math.BigDecimal.valueOf(n).setScale(p, java.math.RoundingMode.HALF_UP).doubleValue();
double temp = Math.pow(10, p);
retval = Math.round(n*temp)/temp;
}
else {
retval = Math.round(n);
}
} }
return retval; return retval;
@ -87,22 +81,7 @@ final class MathX {
retval = Double.NaN; retval = Double.NaN;
} }
else { else {
if (p != 0) { retval = java.math.BigDecimal.valueOf(n).setScale(p, java.math.RoundingMode.UP).doubleValue();
double temp = Math.pow(10, p);
double nat = Math.abs(n*temp);
retval = sign(n) *
((nat == (long) nat)
? nat / temp
: Math.round(nat + 0.5) / temp);
}
else {
double na = Math.abs(n);
retval = sign(n) *
((na == (long) na)
? na
: (long) na + 1);
}
} }
return retval; return retval;
@ -130,13 +109,7 @@ final class MathX {
retval = Double.NaN; retval = Double.NaN;
} }
else { else {
if (p != 0) { retval = java.math.BigDecimal.valueOf(n).setScale(p, java.math.RoundingMode.DOWN).doubleValue();
double temp = Math.pow(10, p);
retval = sign(n) * Math.round((Math.abs(n)*temp) - 0.5)/temp;
}
else {
retval = (long) n;
}
} }
return retval; return retval;

View File

@ -672,6 +672,9 @@ public class TestMathX extends AbstractNumericTestCase {
d = 150.0; p = -2; d = 150.0; p = -2;
assertEquals("round ", 200, MathX.round(d, p)); assertEquals("round ", 200, MathX.round(d, p));
d = 2162.615d; p = 2;
assertEquals("round ", 2162.62d, MathX.round(d, p));
} }
public void testRoundDown() { public void testRoundDown() {

View File

@ -281,4 +281,23 @@ public abstract class BaseTestFormulaEvaluator extends TestCase {
assertEquals(3.5, cellB1.getNumericCellValue(), 0.0); assertEquals(3.5, cellB1.getNumericCellValue(), 0.0);
} }
public void testRounding_bug51339() {
Workbook wb = _testDataProvider.createWorkbook();
Sheet sheet = wb.createSheet("Sheet1");
Row row = sheet.createRow(0);
Cell cellA1 = row.createCell(0);
cellA1.setCellValue(2162.615d);
Cell cellB1 = row.createCell(1);
cellB1.setCellFormula("round(a1,2)");
Cell cellC1 = row.createCell(2);
cellC1.setCellFormula("roundup(a1,2)");
Cell cellD1 = row.createCell(3);
cellD1.setCellFormula("rounddown(a1,2)");
FormulaEvaluator fe = wb.getCreationHelper().createFormulaEvaluator();
assertEquals(2162.62, fe.evaluateInCell(cellB1).getNumericCellValue(), 0.0);
assertEquals(2162.62, fe.evaluateInCell(cellC1).getNumericCellValue(), 0.0);
assertEquals(2162.61, fe.evaluateInCell(cellD1).getNumericCellValue(), 0.0);
}
} }