From 9384cd17849f946484d7504066ec36ea69074123 Mon Sep 17 00:00:00 2001 From: Sergey Solovyev Date: Tue, 6 Dec 2011 12:06:27 +0400 Subject: [PATCH] android_calculator-15: Add numeral systems --- .../android/calculator/CalculatorDisplay.java | 3 ++- .../android/calculator/CalculatorEditor.java | 5 ++-- .../android/calculator/TextHighlighter.java | 9 +++++-- .../calculator/jscl/JsclOperation.java | 2 +- .../android/calculator/math/MathType.java | 4 +-- .../calculator/model/CalculatorEngine.java | 2 +- .../model/FromJsclSimplifyTextProcessor.java | 11 +++++++- .../calculator/model/NumberBuilder.java | 27 +++++++++++-------- .../calculator/TextHighlighterTest.java | 7 ++--- .../model/CalculatorEngineTest.java | 26 +++++++++--------- .../FromJsclSimplifyTextProcessorTest.java | 3 ++- 11 files changed, 61 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java b/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java index 130041d9..88c285f1 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorDisplay.java @@ -14,6 +14,7 @@ import jscl.math.Generic; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.jscl.JsclOperation; +import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.model.ParseException; import org.solovyev.android.calculator.model.TextProcessor; import org.solovyev.android.view.AutoResizeTextView; @@ -34,7 +35,7 @@ public class CalculatorDisplay extends AutoResizeTextView { private JsclOperation jsclOperation = JsclOperation.numeric; @NotNull - private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE, true); + private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE, true, CalculatorEngine.instance.getEngine()); @Nullable private Generic genericResult; diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java b/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java index 7e280a48..aad53065 100644 --- a/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java +++ b/src/main/java/org/solovyev/android/calculator/CalculatorEditor.java @@ -7,15 +7,16 @@ package org.solovyev.android.calculator; import android.content.Context; import android.graphics.Color; -import android.os.Build; import android.text.Html; import android.util.AttributeSet; import android.util.Log; import android.view.ContextMenu; import android.widget.EditText; import org.jetbrains.annotations.NotNull; +import org.solovyev.android.calculator.model.CalculatorEngine; import org.solovyev.android.calculator.model.ParseException; import org.solovyev.android.calculator.model.TextProcessor; +import org.solovyev.common.math.calculators.Calculator; /** * User: serso @@ -27,7 +28,7 @@ public class CalculatorEditor extends EditText { private boolean highlightText = true; @NotNull - private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE, false); + private final static TextProcessor textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine()); public CalculatorEditor(Context context) { super(context); diff --git a/src/main/java/org/solovyev/android/calculator/TextHighlighter.java b/src/main/java/org/solovyev/android/calculator/TextHighlighter.java index 676571ca..18a9c5a3 100644 --- a/src/main/java/org/solovyev/android/calculator/TextHighlighter.java +++ b/src/main/java/org/solovyev/android/calculator/TextHighlighter.java @@ -6,6 +6,7 @@ package org.solovyev.android.calculator; +import jscl.MathContext; import org.jetbrains.annotations.NotNull; import org.solovyev.android.calculator.math.MathType; import org.solovyev.android.calculator.model.NumberBuilder; @@ -20,6 +21,9 @@ import org.solovyev.common.utils.MutableObject; */ public class TextHighlighter implements TextProcessor { + @NotNull + public final MathContext mathContext; + public static class Result implements CharSequence { @NotNull @@ -63,9 +67,10 @@ public class TextHighlighter implements TextProcessor { private final int colorBlue; private final boolean simpleFormat; - public TextHighlighter(int baseColor, boolean simpleFormat) { + public TextHighlighter(int baseColor, boolean simpleFormat, @NotNull MathContext mathContext) { this.color = baseColor; this.simpleFormat = simpleFormat; + this.mathContext = mathContext; //this.colorRed = Color.red(baseColor); this.colorRed = (baseColor >> 16) & 0xFF; //this.colorGreen = Color.green(baseColor); @@ -86,7 +91,7 @@ public class TextHighlighter implements TextProcessor { int numberOffset = 0; - final NumberBuilder numberBuilder = new NumberBuilder(simpleFormat); + final NumberBuilder numberBuilder = new NumberBuilder(simpleFormat, mathContext.getNumeralBase()); for (int i = 0; i < text.length(); i++) { MathType.Result mathType = MathType.getType(text, i); diff --git a/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java b/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java index 4f2b3235..3f0487a2 100644 --- a/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java +++ b/src/main/java/org/solovyev/android/calculator/jscl/JsclOperation.java @@ -16,7 +16,7 @@ import org.solovyev.android.calculator.model.TextProcessor; public enum JsclOperation { - simplify(new FromJsclSimplifyTextProcessor()) { + simplify(new FromJsclSimplifyTextProcessor(CalculatorEngine.instance.getEngine())) { @NotNull @Override public String evaluate(@NotNull String expression) throws ParseException { 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 6255b3b3..056e0003 100644 --- a/src/main/java/org/solovyev/android/calculator/math/MathType.java +++ b/src/main/java/org/solovyev/android/calculator/math/MathType.java @@ -20,7 +20,7 @@ import java.util.*; public enum MathType { -/* numeral_base(50, true, false) { + numeral_base(50, true, false) { private final List tokens = new ArrayList(10); { @@ -37,7 +37,7 @@ public enum MathType { public List getTokens() { return tokens; } - },*/ + }, dot(200, true, true, ".") { @Override diff --git a/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java b/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java index df3835da..f98d89ac 100644 --- a/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java +++ b/src/main/java/org/solovyev/android/calculator/model/CalculatorEngine.java @@ -338,7 +338,7 @@ public enum CalculatorEngine { } public void setDefaultAngleUnits(@NotNull AngleUnit angleUnits) { - getEngine().setDefaultAngleUnit(angleUnits); + getEngine().setAngleUnits(angleUnits); } // for tests only 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 feec68c0..07c54dd8 100644 --- a/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java +++ b/src/main/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessor.java @@ -1,5 +1,7 @@ package org.solovyev.android.calculator.model; +import jscl.MathContext; +import jscl.MathEngine; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.math.MathType; @@ -14,12 +16,19 @@ import java.util.List; */ public class FromJsclSimplifyTextProcessor implements TextProcessor { + @NotNull + private final MathContext mathContext; + + public FromJsclSimplifyTextProcessor(@NotNull MathContext mathContext) { + this.mathContext = mathContext; + } + @NotNull @Override public String process(@NotNull String s) throws ParseException { final StringBuilder sb = new StringBuilder(); - final NumberBuilder numberBuilder = new NumberBuilder(true); + final NumberBuilder numberBuilder = new NumberBuilder(true, mathContext.getNumeralBase()); for (int i = 0; i < s.length(); i++) { final MathType.Result mathTypeResult = MathType.getType(s, i); diff --git a/src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java b/src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java index 1bf14e34..96072790 100644 --- a/src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java +++ b/src/main/java/org/solovyev/android/calculator/model/NumberBuilder.java @@ -6,6 +6,7 @@ package org.solovyev.android.calculator.model; +import jscl.NumeralBase; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.solovyev.android.calculator.math.MathType; @@ -30,11 +31,16 @@ public class NumberBuilder { private final boolean simpleFormat; - /*@Nullable + @NotNull + private final NumeralBase defaultNumeralBase; + + @Nullable private NumeralBase nb; -*/ - public NumberBuilder(boolean simpleFormat) { + + public NumberBuilder(boolean simpleFormat, @NotNull NumeralBase defaultNumeralBase) { this.simpleFormat = simpleFormat; + this.defaultNumeralBase = defaultNumeralBase; + this.nb = defaultNumeralBase; } @NotNull @@ -42,17 +48,17 @@ public class NumberBuilder { number = null; final MathType.Result possibleResult; - if ((CollectionsUtils.contains(mathTypeResult.getMathType(), MathType.digit, /*MathType.numeral_base,*/ MathType.dot, MathType.grouping_separator, MathType.power_10) || + if ((CollectionsUtils.contains(mathTypeResult.getMathType(), MathType.digit, MathType.numeral_base, MathType.dot, MathType.grouping_separator, MathType.power_10) || isSignAfterE(mathTypeResult)) && numeralBaseCheck(mathTypeResult)) { if (numberBuilder == null) { numberBuilder = new StringBuilder(); } - /*if (mathTypeResult.getMathType() != MathType.numeral_base) {*/ + if (mathTypeResult.getMathType() != MathType.numeral_base) { numberBuilder.append(mathTypeResult.getMatch()); - /*} else { + } else { nb = NumeralBase.getByPrefix(mathTypeResult.getMatch()); - }*/ + } possibleResult = null; } else { @@ -63,7 +69,7 @@ public class NumberBuilder { } private boolean numeralBaseCheck( @NotNull MathType.Result mathType ) { - /*if ( mathType.getMathType() == MathType.digit ) { + if ( mathType.getMathType() == MathType.digit ) { final Character ch = mathType.getMatch().charAt(0); if ( NumeralBase.hex.getAcceptableCharacters().contains(ch) && !NumeralBase.dec.getAcceptableCharacters().contains(ch) ) { if ( nb == NumeralBase.hex ) { @@ -76,8 +82,7 @@ public class NumberBuilder { } } else { return true; - }*/ - return true; + } } private boolean isSignAfterE(@NotNull MathType.Result mathTypeResult) { @@ -113,7 +118,7 @@ public class NumberBuilder { } numberBuilder = null; - /*nb = null;*/ + nb = defaultNumeralBase; } else { number = null; } diff --git a/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java b/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java index 2a14a103..b1d609ee 100644 --- a/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java +++ b/src/test/java/org/solovyev/android/calculator/TextHighlighterTest.java @@ -6,6 +6,7 @@ package org.solovyev.android.calculator; +import jscl.JsclMathEngine; import junit.framework.Assert; import org.junit.Test; import org.solovyev.android.calculator.model.TextProcessor; @@ -22,7 +23,7 @@ public class TextHighlighterTest { @Test public void testProcess() throws Exception { - TextProcessor textHighlighter = new TextHighlighter(0, true); + TextProcessor textHighlighter = new TextHighlighter(0, true, JsclMathEngine.instance); final Random random = new Random(new Date().getTime()); for (int i = 0; i < 1000; i++) { @@ -44,14 +45,14 @@ public class TextHighlighterTest { Assert.assertEquals("1 000 000", textHighlighter.process("1000000").toString()); Assert.assertEquals("1 000 000", textHighlighter.process("1000000").toString()); - textHighlighter = new TextHighlighter(0, false); + textHighlighter = new TextHighlighter(0, false, JsclMathEngine.instance); Assert.assertEquals("0.1E3", textHighlighter.process("0.1E3").toString()); Assert.assertEquals("1E3", textHighlighter.process("1E3").toString()); Assert.assertEquals("1 000 000E3", textHighlighter.process("1000000E3").toString()); Assert.assertEquals("-1 000 000E3", textHighlighter.process("-1000000E3").toString()); Assert.assertEquals("-1 000 000E-3", textHighlighter.process("-1000000E-3").toString()); Assert.assertEquals("-1 000 000E-30000", textHighlighter.process("-1000000E-30000").toString()); - textHighlighter = new TextHighlighter(0, true); + textHighlighter = new TextHighlighter(0, true, JsclMathEngine.instance); textHighlighter.process("cannot calculate 3^10^10 !!!\n" + " unable to enter 0. FIXED\n" + 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 af09e978..f6367813 100644 --- a/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java +++ b/src/test/java/org/solovyev/android/calculator/model/CalculatorEngineTest.java @@ -94,27 +94,27 @@ public class CalculatorEngineTest { Assert.assertEquals("1", cm.evaluate(JsclOperation.simplify, "eq( 1, 1)").getResult()); Assert.assertEquals("1", cm.evaluate(JsclOperation.numeric, "lg(10)").getResult()); Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "2+2").getResult()); - final AngleUnit defaultAngleUnit = cm.getEngine().getDefaultAngleUnit(); + final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits(); try { - cm.getEngine().setDefaultAngleUnit(AngleUnit.rad); + cm.getEngine().setAngleUnits(AngleUnit.rad); Assert.assertEquals("-0.757", cm.evaluate(JsclOperation.numeric, "sin(4)").getResult()); Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "asin(0.5)").getResult()); Assert.assertEquals("-0.396", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)").getResult()); Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)").getResult()); Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)").getResult()); } finally { - cm.getEngine().setDefaultAngleUnit(defaultAngleUnit); + cm.getEngine().setAngleUnits(defaultAngleUnit); } Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "e^2").getResult()); Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(1)^2").getResult()); Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(2)").getResult()); Assert.assertEquals("2+i", cm.evaluate(JsclOperation.numeric, "2*1+√(-1)").getResult()); try { - cm.getEngine().setDefaultAngleUnit(AngleUnit.rad); + cm.getEngine().setAngleUnits(AngleUnit.rad); Assert.assertEquals("0.921+3.142i", cm.evaluate(JsclOperation.numeric, "ln(5cosh(38π√(2cos(2))))").getResult()); Assert.assertEquals("-3.41+3.41i", cm.evaluate(JsclOperation.numeric, "(5tan(2i)+2i)/(1-i)").getResult()); } finally { - cm.getEngine().setDefaultAngleUnit(defaultAngleUnit); + cm.getEngine().setAngleUnits(defaultAngleUnit); } Assert.assertEquals("7.389i", cm.evaluate(JsclOperation.numeric, "iexp(2)").getResult()); Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+iexp(2)").getResult()); @@ -152,7 +152,7 @@ public class CalculatorEngineTest { CalculatorEngine.instance.getVarsRegister().add(new Var.Builder("si", 5d)); try { - cm.getEngine().setDefaultAngleUnit(AngleUnit.rad); + cm.getEngine().setAngleUnits(AngleUnit.rad); Assert.assertEquals("0.451", cm.evaluate(JsclOperation.numeric, "acos(0.8999999999999811)").getResult()); Assert.assertEquals("-0.959", cm.evaluate(JsclOperation.numeric, "sin(5)").getResult()); Assert.assertEquals("-4.795", cm.evaluate(JsclOperation.numeric, "sin(5)si").getResult()); @@ -160,7 +160,7 @@ public class CalculatorEngineTest { Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "si*sin(5)si").getResult()); Assert.assertEquals("-3.309", cm.evaluate(JsclOperation.numeric, "sisin(5si)si").getResult()); } finally { - cm.getEngine().setDefaultAngleUnit(defaultAngleUnit); + cm.getEngine().setAngleUnits(defaultAngleUnit); } CalculatorEngine.instance.getVarsRegister().add(new Var.Builder("s", 1d)); @@ -252,12 +252,12 @@ public class CalculatorEngineTest { } catch (ParseException e) { } - final AngleUnit defaultAngleUnit = cm.getEngine().getDefaultAngleUnit(); + final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits(); try { - cm.getEngine().setDefaultAngleUnit(AngleUnit.rad); + cm.getEngine().setAngleUnits(AngleUnit.rad); Assert.assertEquals("0.739", cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(cos(1))))))))))))))))))))))))))))))))))))").getResult()); } finally { - cm.getEngine().setDefaultAngleUnit(defaultAngleUnit); + cm.getEngine().setAngleUnits(defaultAngleUnit); } CalculatorEngine.instance.getVarsRegister().add(new Var.Builder("si", 5d)); @@ -327,9 +327,9 @@ public class CalculatorEngineTest { public void testDegrees() throws Exception { final CalculatorEngine cm = CalculatorEngine.instance; - final AngleUnit defaultAngleUnit = cm.getEngine().getDefaultAngleUnit(); + final AngleUnit defaultAngleUnit = cm.getEngine().getAngleUnits(); try { - cm.getEngine().setDefaultAngleUnit(AngleUnit.rad); + cm.getEngine().setAngleUnits(AngleUnit.rad); cm.setPrecision(3); try { Assert.assertEquals("0.017", cm.evaluate(JsclOperation.numeric, "°")); @@ -350,7 +350,7 @@ public class CalculatorEngineTest { Assert.assertEquals("∂(cos(t), t, t,1°)", cm.evaluate(JsclOperation.simplify, "∂(cos(t),t,t,1°)").getResult()); } finally { - cm.getEngine().setDefaultAngleUnit(defaultAngleUnit); + cm.getEngine().setAngleUnits(defaultAngleUnit); } } } diff --git a/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java b/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java index fb501c43..a0f05808 100644 --- a/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java +++ b/src/test/java/org/solovyev/android/calculator/model/FromJsclSimplifyTextProcessorTest.java @@ -1,5 +1,6 @@ package org.solovyev.android.calculator.model; +import jscl.JsclMathEngine; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; @@ -20,7 +21,7 @@ public class FromJsclSimplifyTextProcessorTest { @Test public void testProcess() throws Exception { - FromJsclSimplifyTextProcessor tp = new FromJsclSimplifyTextProcessor(); + FromJsclSimplifyTextProcessor tp = new FromJsclSimplifyTextProcessor(JsclMathEngine.instance); Assert.assertEquals("(e)", tp.process("(2.718281828459045)")); Assert.assertEquals("ee", tp.process("2.718281828459045*2.718281828459045")); Assert.assertEquals("((e)(e))", tp.process("((2.718281828459045)*(2.718281828459045))"));