android_calculator-15: Add numeral systems

This commit is contained in:
Sergey Solovyev 2011-12-06 12:06:27 +04:00
parent 4bcd26faec
commit 9384cd1784
11 changed files with 61 additions and 38 deletions

View File

@ -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.Result> textHighlighter = new TextHighlighter(Color.WHITE, true);
private final static TextProcessor<TextHighlighter.Result> textHighlighter = new TextHighlighter(Color.WHITE, true, CalculatorEngine.instance.getEngine());
@Nullable
private Generic genericResult;

View File

@ -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.Result> textHighlighter = new TextHighlighter(Color.WHITE, false);
private final static TextProcessor<TextHighlighter.Result> textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine());
public CalculatorEditor(Context context) {
super(context);

View File

@ -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<TextHighlighter.Result> {
@NotNull
public final MathContext mathContext;
public static class Result implements CharSequence {
@NotNull
@ -63,9 +67,10 @@ public class TextHighlighter implements TextProcessor<TextHighlighter.Result> {
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<TextHighlighter.Result> {
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);

View File

@ -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 {

View File

@ -20,7 +20,7 @@ import java.util.*;
public enum MathType {
/* numeral_base(50, true, false) {
numeral_base(50, true, false) {
private final List<String> tokens = new ArrayList<String>(10);
{
@ -37,7 +37,7 @@ public enum MathType {
public List<String> getTokens() {
return tokens;
}
},*/
},
dot(200, true, true, ".") {
@Override

View File

@ -338,7 +338,7 @@ public enum CalculatorEngine {
}
public void setDefaultAngleUnits(@NotNull AngleUnit angleUnits) {
getEngine().setDefaultAngleUnit(angleUnits);
getEngine().setAngleUnits(angleUnits);
}
// for tests only

View File

@ -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<String> {
@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);

View File

@ -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;
}

View File

@ -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" +

View File

@ -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);
}
}
}

View File

@ -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))"));