From c17abf116cc6c36b30024cb14a9045fe81507129 Mon Sep 17 00:00:00 2001 From: "Amol S. Deshmukh" Date: Wed, 9 Aug 2006 20:03:36 +0000 Subject: [PATCH] bugfix 38396: Exponential numbers are now handled by the formula parser git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@430132 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/hssf/model/FormulaParser.java | 38 ++++++- .../poi/hssf/model/TestFormulaParser.java | 98 +++++++++++++++++++ 2 files changed, 131 insertions(+), 5 deletions(-) diff --git a/src/java/org/apache/poi/hssf/model/FormulaParser.java b/src/java/org/apache/poi/hssf/model/FormulaParser.java index e15e7cff8..ae2b14a54 100644 --- a/src/java/org/apache/poi/hssf/model/FormulaParser.java +++ b/src/java/org/apache/poi/hssf/model/FormulaParser.java @@ -229,18 +229,36 @@ public class FormulaParser { } + /** Get the exponent for numbers of form 1.3E21 */ + private String GetExponent() { + StringBuffer retval = new StringBuffer(); + String sign = ""; + GetChar(); + if ('-' == look) { + sign = "-"; + GetChar(); + } + while (IsDigit(look)) { + retval.append(look); + GetChar(); + } + if (retval.length() > 0) { + retval.insert(0, sign); + } + return retval.toString(); + } + /** Get a Number */ private String GetNum() { - String Value =""; + StringBuffer value = new StringBuffer(); if (!IsDigit(look)) Expected("Integer"); while (IsDigit(look)){ - Value = Value + look; + value.append(look); GetChar(); } SkipWhite(); - return Value; + return value.toString(); } - /** Output a String with Tab */ private void Emit(String s){ System.out.print(TAB+s); @@ -482,8 +500,18 @@ public class FormulaParser { Match('.'); String decimalPart = null; if (IsDigit(look)) number = number +"."+ GetNum(); //this also takes care of someone entering "1234." + if ('E' == look) { + String exponent = GetExponent(); + number += 'E' + exponent; + } tokens.add(new NumberPtg(number)); - } else { + } + else if ('E' == look) { + String exponent = GetExponent(); + number += 'E'+exponent; + tokens.add(new NumberPtg(number)); + } + else { tokens.add(getNumberPtgFromString(number)); //TODO:what if the number is too big to be a short? ..add factory to return Int or Number! } } diff --git a/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java b/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java index 812a42d71..b77353f8b 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java +++ b/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java @@ -404,6 +404,104 @@ public class TestFormulaParser extends TestCase { } + // bug 38396 : Formula with exponential numbers not parsed correctly. + public void testExponentialParsing() { + FormulaParser fp = new FormulaParser("1.3E21/2", null); + fp.parse(); + Ptg[] ptgs = fp.getRPNPtg(); + assertTrue("three tokens expected, got " + ptgs.length, ptgs.length == 3); + assertTrue("NumberPtg", (ptgs[0] instanceof NumberPtg)); + assertTrue("IntPtg", (ptgs[1] instanceof IntPtg)); + assertTrue("DividePtg", (ptgs[2] instanceof DividePtg)); + + fp = new FormulaParser("1322E21/2", null); + fp.parse(); + ptgs = fp.getRPNPtg(); + assertTrue("three tokens expected, got " + ptgs.length, ptgs.length == 3); + assertTrue("NumberPtg", (ptgs[0] instanceof NumberPtg)); + assertTrue("IntPtg", (ptgs[1] instanceof IntPtg)); + assertTrue("DividePtg", (ptgs[2] instanceof DividePtg)); + + fp = new FormulaParser("1.3E1/2", null); + fp.parse(); + ptgs = fp.getRPNPtg(); + assertTrue("three tokens expected, got " + ptgs.length, ptgs.length == 3); + assertTrue("NumberPtg", (ptgs[0] instanceof NumberPtg)); + assertTrue("IntPtg", (ptgs[1] instanceof IntPtg)); + assertTrue("DividePtg", (ptgs[2] instanceof DividePtg)); + + } + public void testExponentialInSheet() throws Exception { + HSSFWorkbook wb = new HSSFWorkbook(); + + wb.createSheet("Cash_Flow");; + + HSSFSheet sheet = wb.createSheet("Test"); + HSSFRow row = sheet.createRow(0); + HSSFCell cell = row.createCell((short)0); + String formula = null; + + cell.setCellFormula("1.3E21/3"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "1.3E21/3", formula); + + cell.setCellFormula("-1.3E21/3"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "-1.3E21/3", formula); + + cell.setCellFormula("1322E21/3"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "1.322E24/3", formula); + + cell.setCellFormula("-1322E21/3"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "-1.322E24/3", formula); + + cell.setCellFormula("1.3E1/3"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "13.0/3", formula); + + cell.setCellFormula("-1.3E1/3"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "-13.0/3", formula); + + cell.setCellFormula("1.3E-4/3"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "1.3E-4/3", formula); + + cell.setCellFormula("-1.3E-4/3"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "-1.3E-4/3", formula); + + cell.setCellFormula("13E-15/3"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "1.3E-14/3", formula); + + cell.setCellFormula("-13E-15/3"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "-1.3E-14/3", formula); + + cell.setCellFormula("1.3E3/3"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "1300.0/3", formula); + + cell.setCellFormula("-1.3E3/3"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "-1300.0/3", formula); + + cell.setCellFormula("1300000000000000/3"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "1.3E15/3", formula); + + cell.setCellFormula("-1300000000000000/3"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "-1.3E15/3", formula); + + cell.setCellFormula("-10E-1/3.1E2*4E3/3E4"); + formula = cell.getCellFormula(); + assertEquals("Exponential formula string", "-1.0/310.0*4000.0/30000.0", formula); + } + public static void main(String [] args) { System.out.println("Testing org.apache.poi.hssf.record.formula.FormulaParser"); junit.textui.TestRunner.run(TestFormulaParser.class);