diff --git a/pom.xml b/pom.xml index 5732e6ad..aae643d2 100644 --- a/pom.xml +++ b/pom.xml @@ -53,6 +53,13 @@ ${additionalLibs}/jscl.jar--> + + net.sf.opencsv + opencsv + 2.0 + test + + org.simpleframework simple-xml diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorModel.java b/src/main/java/org/solovyev/android/calculator/CalculatorModel.java index d7e1c7c1..7e69fa90 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorModel.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorModel.java @@ -285,7 +285,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl localNumberOffset = new MutableObject(0); numberBuilder.process(text1, mathType, localNumberOffset); diff --git a/src/main/java/org/solovyev/android/calculator/math/MathType.java b/src/main/java/org/solovyev/android/calculator/math/MathType.java index fe20a4f0..5abf20c8 100644 --- a/src/main/java/org/solovyev/android/calculator/math/MathType.java +++ b/src/main/java/org/solovyev/android/calculator/math/MathType.java @@ -318,12 +318,14 @@ public enum MathType { /** * Method determines mathematical entity type for text substring starting from ith index * + * * @param text analyzed text * @param i index which points to start of substring + * @param hexMode * @return math entity type of substring starting from ith index of specified text */ @NotNull - public static Result getType(@NotNull String text, int i) { + public static Result getType(@NotNull String text, int i, boolean hexMode) { if (i < 0) { throw new IllegalArgumentException("I must be more or equals to 0."); } else if (i >= text.length() && i != 0) { @@ -338,7 +340,7 @@ public enum MathType { final String s = CollectionsUtils.find(mathType.getTokens(), startsWithFinder); if (s != null) { if ( s.length() == 1 ) { - if (JsclMathEngine.instance.getNumeralBase() == NumeralBase.hex) { + if (hexMode || JsclMathEngine.instance.getNumeralBase() == NumeralBase.hex) { final Character ch = s.charAt(0); if ( NumeralBase.hex.getAcceptableCharacters().contains(ch) ) { return new Result(MathType.digit, s); diff --git a/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java b/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java index 930c8364..c163155f 100644 --- a/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java +++ b/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java @@ -35,7 +35,7 @@ public class FromJsclSimplifyTextProcessor implements TextProcessor { MathType.Result mathTypeResult = null; MathType.Result mathTypeBefore = null; + final StringBuilder sb = new StringBuilder(s); + + final NumberBuilder nb = new NumberBuilder(true, CalculatorEngine.instance.getEngine().getNumeralBase()); for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == ' ') continue; startsWithFinder.setI(i); mathTypeBefore = mathTypeResult == null ? null : mathTypeResult; - mathTypeResult = MathType.getType(s, i); + mathTypeResult = MathType.getType(s, i, nb.isHexMode()); + + nb.process(sb, mathTypeResult, null); if (mathTypeBefore != null) { diff --git a/src/test/java/org/solovyev/android/calculator/math/MathTypeTest.java b/src/test/java/org/solovyev/android/calculator/math/MathTypeTest.java index 38c03982..b3fef984 100644 --- a/src/test/java/org/solovyev/android/calculator/math/MathTypeTest.java +++ b/src/test/java/org/solovyev/android/calculator/math/MathTypeTest.java @@ -25,24 +25,24 @@ public class MathTypeTest { @Test public void testGetType() throws Exception { - Assert.assertEquals(MathType.function, MathType.getType("sin", 0).getMathType()); - Assert.assertEquals(MathType.text, MathType.getType("sn", 0).getMathType()); - Assert.assertEquals(MathType.text, MathType.getType("s", 0).getMathType()); - Assert.assertEquals(MathType.text, MathType.getType("", 0).getMathType()); + Assert.assertEquals(MathType.function, MathType.getType("sin", 0, false).getMathType()); + Assert.assertEquals(MathType.text, MathType.getType("sn", 0, false).getMathType()); + Assert.assertEquals(MathType.text, MathType.getType("s", 0, false).getMathType()); + Assert.assertEquals(MathType.text, MathType.getType("", 0, false).getMathType()); try { - Assert.assertEquals(MathType.text, MathType.getType("22", -1).getMathType()); + Assert.assertEquals(MathType.text, MathType.getType("22", -1, false).getMathType()); Assert.fail(); } catch (IllegalArgumentException e) { } try { - Assert.assertEquals(MathType.text, MathType.getType("22", 2).getMathType()); + Assert.assertEquals(MathType.text, MathType.getType("22", 2, false).getMathType()); Assert.fail(); } catch (IllegalArgumentException e) { } - Assert.assertEquals("atanh", MathType.getType("atanh", 0).getMatch()); + Assert.assertEquals("atanh", MathType.getType("atanh", 0, false).getMatch()); } /* @Test diff --git a/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java b/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java index 92d8009f..2ec50e0f 100644 --- a/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java +++ b/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java @@ -6,6 +6,7 @@ package org.solovyev.android.calculator.model; import jscl.AngleUnit; +import jscl.JsclMathEngine; import jscl.NumeralBase; import jscl.math.Expression; import jscl.math.Generic; @@ -275,16 +276,23 @@ public class CalculatorEngineTest { public void testRounding() throws Exception { final CalculatorEngine cm = CalculatorEngine.instance; - DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault()); - decimalGroupSymbols.setDecimalSeparator('.'); - decimalGroupSymbols.setGroupingSeparator('\''); - cm.setDecimalGroupSymbols(decimalGroupSymbols); - cm.setPrecision(2); - Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getResult()); - cm.setPrecision(10); - Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getResult()); - Assert.assertEquals("123'456'789", cm.evaluate(JsclOperation.numeric, "1.234567890E8").getResult()); - Assert.assertEquals("1'234'567'890.1", cm.evaluate(JsclOperation.numeric, "1.2345678901E9").getResult()); + try { + DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault()); + decimalGroupSymbols.setDecimalSeparator('.'); + decimalGroupSymbols.setGroupingSeparator('\''); + cm.setDecimalGroupSymbols(decimalGroupSymbols); + cm.setPrecision(2); + Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getResult()); + cm.setPrecision(10); + Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getResult()); + Assert.assertEquals("123'456'789", cm.evaluate(JsclOperation.numeric, "1.234567890E8").getResult()); + Assert.assertEquals("1'234'567'890.1", cm.evaluate(JsclOperation.numeric, "1.2345678901E9").getResult()); + } finally { + DecimalFormatSymbols decimalGroupSymbols = new DecimalFormatSymbols(Locale.getDefault()); + decimalGroupSymbols.setDecimalSeparator('.'); + decimalGroupSymbols.setGroupingSeparator(JsclMathEngine.GROUPING_SEPARATOR_DEFAULT.charAt(0)); + cm.setDecimalGroupSymbols(decimalGroupSymbols); + } } @Test @@ -359,6 +367,15 @@ public class CalculatorEngineTest { public void testNumeralSystems() throws Exception { final CalculatorEngine cm = CalculatorEngine.instance; + Assert.assertEquals("11 259 375", cm.evaluate(JsclOperation.numeric, "0x:abcdef").getResult()); + Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:abcdef*e").getResult()); + Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "e*0x:abcdef").getResult()); + Assert.assertEquals("2.718", cm.evaluate(JsclOperation.numeric, "e*0x:abcdef/0x:abcdef").getResult()); + Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "0x:abcdef*e*0x:abcdef/0x:abcdef").getResult()); + Assert.assertEquals("30 606 154.462", cm.evaluate(JsclOperation.numeric, "c+0x:abcdef*e*0x:abcdef/0x:abcdef-c+0x:c-0x:c").getResult()); + Assert.assertEquals("1 446 257 064 651.832", cm.evaluate(JsclOperation.numeric, "28*28 * sin(28) - 0b:1101 + √(28) + exp ( 28) ").getResult()); + Assert.assertEquals("13", cm.evaluate(JsclOperation.numeric, "0b:1101").getResult()); + final NumeralBase defaultNumeralBase = cm.getEngine().getNumeralBase(); try{ cm.getEngine().setNumeralBase(NumeralBase.bin); diff --git a/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java b/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java new file mode 100644 index 00000000..0d19a893 --- /dev/null +++ b/src/test/java/org/solovyev/android/calculator/model/NumeralBaseTest.java @@ -0,0 +1,107 @@ +package org.solovyev.android.calculator.model; + +import au.com.bytecode.opencsv.CSVReader; +import jscl.JsclMathEngine; +import jscl.MathEngine; +import jscl.math.Expression; +import jscl.text.ParseException; +import org.jetbrains.annotations.NotNull; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.solovyev.android.calculator.jscl.JsclOperation; +import org.solovyev.common.utils.Converter; + +import java.io.InputStreamReader; + +/** + * User: serso + * Date: 12/14/11 + * Time: 4:16 PM + */ +public class NumeralBaseTest { + + @BeforeClass + public static void setUp() throws Exception { + CalculatorEngine.instance.init(null, null); + CalculatorEngine.instance.setPrecision(3); + CalculatorEngine.instance.setThreadKiller(new CalculatorEngine.ThreadKillerImpl()); + } + + @Test + public void testConversion() throws Exception { + CSVReader reader = null; + try { + final MathEngine me = JsclMathEngine.instance; + + reader = new CSVReader(new InputStreamReader(NumeralBaseTest.class.getResourceAsStream("/jscl/math/nb_table.csv")), '\t'); + + // skip first line + reader.readNext(); + + String[] line = reader.readNext(); + for (; line != null; line = reader.readNext()) { + testExpression(line, new DummyExpression()); + testExpression(line, new Expression1()); + testExpression(line, new Expression2()); + testExpression(line, new Expression3()); + } + } finally { + if (reader != null) { + reader.close(); + } + } + } + + public static void testExpression(@NotNull String[] line, @NotNull Converter converter) throws ParseException, CalculatorEvalException, CalculatorParseException { + final String dec = line[0]; + final String hex = "0x:" + line[1]; + final String bin = "0b:" + line[2]; + + final String decExpression = converter.convert(dec); + final String decResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, decExpression).getResult(); + final String hexExpression = converter.convert(hex); + final String hexResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, hexExpression).getResult(); + final String binExpression = converter.convert(bin); + final String binResult = CalculatorEngine.instance.evaluate(JsclOperation.numeric, binExpression).getResult(); + + Assert.assertEquals("dec-hex: " + decExpression + " : " + hexExpression, decResult, hexResult); + Assert.assertEquals("dec-bin: " + decExpression + " : " + binExpression, decResult, binResult); + } + + private static class DummyExpression implements Converter { + + @NotNull + @Override + public String convert(@NotNull String s) { + return s; + } + } + + private static class Expression1 implements Converter { + + @NotNull + @Override + public String convert(@NotNull String s) { + return s + "*" + s; + } + } + + private static class Expression2 implements Converter { + + @NotNull + @Override + public String convert(@NotNull String s) { + return s + "*" + s + " * sin(" + s + ") - 0b:1101"; + } + } + + private static class Expression3 implements Converter { + + @NotNull + @Override + public String convert(@NotNull String s) { + return s + "*" + s + " * sin(" + s + ") - 0b:1101 + √(" + s + ") + exp ( " + s + ")"; + } + } +} diff --git a/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java b/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java index 3f023dac..3bce2998 100644 --- a/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java +++ b/src/test/java/org/solovyev/android/calculator/model/ToJsclTextProcessorTest.java @@ -61,6 +61,20 @@ public class ToJsclTextProcessorTest { Assert.assertEquals( "E+1.2", preprocessor.process("E+1.2").toString()); Assert.assertEquals( "E(-1.2)", preprocessor.process("E(-1.2)").toString()); Assert.assertEquals( "EE", preprocessor.process("EE").toString()); + + Assert.assertEquals( "0x:abcdef", preprocessor.process("0x:abcdef").toString()); + Assert.assertEquals( "0x:abcdef", preprocessor.process("0x:a bc def").toString()); + Assert.assertEquals( "0x:abcdef", preprocessor.process("0x:a bc def").toString()); + Assert.assertEquals( "0x:abcdef*0*x", preprocessor.process("0x:a bc def*0x").toString()); + Assert.assertEquals( "0x:abcdef001*0*x", preprocessor.process("0x:a bc def001*0x").toString()); + Assert.assertEquals( "0x:abcdef001*0*c", preprocessor.process("0x:a bc def001*0c").toString()); + Assert.assertEquals( "0x:abcdef001*c", preprocessor.process("0x:a bc def001*c").toString()); + Assert.assertEquals( "0b:1101", preprocessor.process("0b:1101").toString()); + Assert.assertEquals( "0x:1c", preprocessor.process("0x:1c").toString()); + Assert.assertEquals( "0x:1c", preprocessor.process(" 0x:1c").toString()); + Assert.assertEquals( "0x:1c*0x:1c*sin(0x:1c)-0b:1101+√(0x:1c)+exp(0x:1c)", preprocessor.process("0x:1c*0x:1c * sin(0x:1c) - 0b:1101 + √(0x:1c) + exp ( 0x:1c)").toString()); + Assert.assertEquals( "0x:1c*0x:1c*sin(0x:1c)-0b:1101+√(0x:1c)+exp(0x:1c)", preprocessor.process("0x:1c*0x:1c * sin(0x:1c) - 0b:1101 + √(0x:1c) + exp ( 0x:1c)").toString()); + try { preprocessor.process("ln()"); Assert.fail();