support for entering E number

This commit is contained in:
serso 2011-11-12 18:49:26 +04:00
parent 24fd81fbc0
commit 66da31b20e
6 changed files with 76 additions and 40 deletions

View File

@ -10,6 +10,7 @@
a:id="@+id/plusButton" a:id="@+id/plusButton"
calc:directionTextScale="0.5" calc:directionTextScale="0.5"
calc:textUp="°" calc:textUp="°"
calc:textDown="E"
a:text="+" a:text="+"
style="?digitButtonStyle" style="?digitButtonStyle"
a:onClick="digitButtonClickHandler"/> a:onClick="digitButtonClickHandler"/>

View File

@ -43,12 +43,7 @@ public enum MathType {
} }
}, },
power_10(300, true, false, "E") { power_10(300, false, false, "E"),
@Override
protected String getSubstituteToJscl(@NotNull String match) {
return POWER_10_JSCL;
}
},
postfix_function(400, false, true) { postfix_function(400, false, true) {
@NotNull @NotNull
@ -260,7 +255,6 @@ public enum MathType {
public static final List<String> openGroupSymbols = Arrays.asList("[]", "()", "{}"); public static final List<String> openGroupSymbols = Arrays.asList("[]", "()", "{}");
public final static Character POWER_10 = 'E'; public final static Character POWER_10 = 'E';
public final static String POWER_10_JSCL = "10^";
public static final String IMAGINARY_NUMBER = "i"; public static final String IMAGINARY_NUMBER = "i";
public static final String IMAGINARY_NUMBER_JSCL = "√(-1)"; public static final String IMAGINARY_NUMBER_JSCL = "√(-1)";

View File

@ -13,11 +13,14 @@ import org.solovyev.common.utils.CollectionsUtils;
import org.solovyev.common.utils.Finder; import org.solovyev.common.utils.Finder;
import org.solovyev.common.utils.MutableObject; import org.solovyev.common.utils.MutableObject;
import java.util.ArrayList;
import java.util.List;
/** /**
* User: serso * User: serso
* Date: 10/23/11 * Date: 10/23/11
* Time: 2:57 PM * Time: 2:57 PM
*/ */
public class NumberBuilder { public class NumberBuilder {
@Nullable @Nullable
@ -36,7 +39,8 @@ public class NumberBuilder {
number = null; number = null;
final MathType.Result possibleResult; final MathType.Result possibleResult;
if (CollectionsUtils.contains(mathTypeResult.getMathType(), MathType.digit, MathType.dot, MathType.grouping_separator, MathType.power_10)) { if (CollectionsUtils.contains(mathTypeResult.getMathType(), MathType.digit, MathType.dot, MathType.grouping_separator, MathType.power_10) ||
isSignAfterE(mathTypeResult)) {
if (numberBuilder == null) { if (numberBuilder == null) {
numberBuilder = new StringBuilder(); numberBuilder = new StringBuilder();
} }
@ -51,17 +55,31 @@ public class NumberBuilder {
return possibleResult == null ? mathTypeResult : possibleResult; return possibleResult == null ? mathTypeResult : possibleResult;
} }
private boolean isSignAfterE(@NotNull MathType.Result mathTypeResult) {
if ("-".equals(mathTypeResult.getMatch()) || "+".equals(mathTypeResult.getMatch())) {
if (numberBuilder != null && numberBuilder.length() > 0) {
if (numberBuilder.charAt(numberBuilder.length() - 1) == MathType.POWER_10) {
return true;
}
}
}
return false;
}
@Nullable @Nullable
public MathType.Result process(@NotNull StringBuilder sb, @Nullable MutableObject<Integer> numberOffset) { public MathType.Result process(@NotNull StringBuilder sb, @Nullable MutableObject<Integer> numberOffset) {
int numberOfGroupingSeparators = 0; int numberOfTokens = 0;
if (numberBuilder != null) { if (numberBuilder != null) {
try { try {
number = numberBuilder.toString(); number = numberBuilder.toString();
for (String groupingSeparator : MathType.grouping_separator.getTokens()) { List<String> tokens = new ArrayList<String>();
tokens.addAll(MathType.grouping_separator.getTokens());
tokens.add("+");
for (String groupingSeparator : tokens) {
String newNumber = number.replace(groupingSeparator, ""); String newNumber = number.replace(groupingSeparator, "");
numberOfGroupingSeparators += number.length() - newNumber.length(); numberOfTokens += number.length() - newNumber.length();
number = newNumber; number = newNumber;
} }
Double.valueOf(number); Double.valueOf(number);
@ -74,11 +92,11 @@ public class NumberBuilder {
number = null; number = null;
} }
return replaceSystemVars(sb, number, numberOfGroupingSeparators, numberOffset); return replaceSystemVars(sb, number, numberOfTokens, numberOffset);
} }
@Nullable @Nullable
private MathType.Result replaceSystemVars(StringBuilder sb, String number, int numberOfGroupingSeparators, @Nullable MutableObject<Integer> numberOffset) { private MathType.Result replaceSystemVars(StringBuilder sb, String number, int numberOfTokens, @Nullable MutableObject<Integer> numberOffset) {
MathType.Result result = null; MathType.Result result = null;
if (number != null) { if (number != null) {
@ -91,11 +109,11 @@ public class NumberBuilder {
}); });
if (var != null) { if (var != null) {
sb.delete(sb.length() - number.length() - numberOfGroupingSeparators, sb.length()); sb.delete(sb.length() - number.length() - numberOfTokens, sb.length());
sb.append(var.getName()); sb.append(var.getName());
result = new MathType.Result(MathType.constant, var.getName()); result = new MathType.Result(MathType.constant, var.getName());
} else { } else {
sb.delete(sb.length() - number.length() - numberOfGroupingSeparators, sb.length()); sb.delete(sb.length() - number.length() - numberOfTokens, sb.length());
final String formattedNumber; final String formattedNumber;
@ -103,9 +121,20 @@ public class NumberBuilder {
int indexOfDot = number.indexOf('.'); int indexOfDot = number.indexOf('.');
if (indexOfDot < 0) { if (indexOfDot < 0) {
formattedNumber = CalculatorEngine.instance.format(Double.valueOf(number), false); int indexOfE = number.indexOf('E');
if (indexOfE < 0) {
formattedNumber = CalculatorEngine.instance.format(Double.valueOf(number), false);
} else {
final String part;
if (indexOfDot != 0) {
part = CalculatorEngine.instance.format(Double.valueOf(number.substring(0, indexOfE)), false);
} else {
part = "";
}
formattedNumber = part + number.substring(indexOfE);
}
} else { } else {
String integerPart = null; final String integerPart;
if (indexOfDot != 0) { if (indexOfDot != 0) {
integerPart = CalculatorEngine.instance.format(Double.valueOf(number.substring(0, indexOfDot)), false); integerPart = CalculatorEngine.instance.format(Double.valueOf(number.substring(0, indexOfDot)), false);
} else { } else {
@ -118,7 +147,7 @@ public class NumberBuilder {
} }
if (numberOffset != null) { if (numberOffset != null) {
numberOffset.setObject(formattedNumber.length() - number.length() - numberOfGroupingSeparators); numberOffset.setObject(formattedNumber.length() - number.length() - numberOfTokens);
} }
sb.append(formattedNumber); sb.append(formattedNumber);
} }

View File

@ -22,7 +22,7 @@ public class TextHighlighterTest {
@Test @Test
public void testProcess() throws Exception { public void testProcess() throws Exception {
final TextProcessor textHighlighter = new TextHighlighter(0, true); TextProcessor textHighlighter = new TextHighlighter(0, true);
final Random random = new Random(new Date().getTime()); final Random random = new Random(new Date().getTime());
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
@ -42,6 +42,16 @@ public class TextHighlighterTest {
Assert.assertEquals(")", textHighlighter.process(")").toString()); Assert.assertEquals(")", textHighlighter.process(")").toString());
Assert.assertEquals(")()(", textHighlighter.process(")()(").toString()); Assert.assertEquals(")()(", textHighlighter.process(")()(").toString());
Assert.assertEquals("1 000 000", textHighlighter.process("1000000").toString()); Assert.assertEquals("1 000 000", textHighlighter.process("1000000").toString());
Assert.assertEquals("1 000 000", textHighlighter.process("1000000").toString());
textHighlighter = new TextHighlighter(0, false);
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.process("cannot calculate 3^10^10 !!!\n" + textHighlighter.process("cannot calculate 3^10^10 !!!\n" +
" unable to enter 0. FIXED\n" + " unable to enter 0. FIXED\n" +

View File

@ -153,6 +153,7 @@ public class CalculatorEngineTest {
Assert.assertEquals("11∞t", cm.evaluate(JsclOperation.numeric, "t11∞").getResult()); Assert.assertEquals("11∞t", cm.evaluate(JsclOperation.numeric, "t11∞").getResult());
Assert.assertEquals("-t+t^3", cm.evaluate(JsclOperation.numeric, "t(t-1)(t+1)").getResult()); Assert.assertEquals("-t+t^3", cm.evaluate(JsclOperation.numeric, "t(t-1)(t+1)").getResult());
Assert.assertEquals("100", cm.evaluate(JsclOperation.numeric, "0.1E3").getResult());
Assert.assertEquals("3.957", cm.evaluate(JsclOperation.numeric, "ln(8)lg(8)+ln(8)").getResult()); Assert.assertEquals("3.957", cm.evaluate(JsclOperation.numeric, "ln(8)lg(8)+ln(8)").getResult());
@ -214,8 +215,8 @@ public class CalculatorEngineTest {
cm.setPrecision(2); cm.setPrecision(2);
Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getResult()); Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getResult());
cm.setPrecision(10); cm.setPrecision(10);
Assert.assertEquals("12'345'678.899999999", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getResult()); Assert.assertEquals("12'345'678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7").getResult());
Assert.assertEquals("123'456'788.99999999", cm.evaluate(JsclOperation.numeric, "1.234567890E8").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()); Assert.assertEquals("1'234'567'890.1", cm.evaluate(JsclOperation.numeric, "1.2345678901E9").getResult());
} }

View File

@ -25,7 +25,7 @@ public class ToJsclTextProcessorTest {
@Test @Test
public void testSpecialCases() throws ParseException { public void testSpecialCases() throws ParseException {
final ToJsclTextProcessor preprocessor = new ToJsclTextProcessor(); final ToJsclTextProcessor preprocessor = new ToJsclTextProcessor();
Assert.assertEquals( "3^10^10", preprocessor.process("3^10^10").toString()); Assert.assertEquals( "3^E10", preprocessor.process("3^E10").toString());
} }
@Test @Test
@ -37,12 +37,12 @@ public class ToJsclTextProcessorTest {
Assert.assertEquals( "()*()", preprocessor.process("[][]").toString()); Assert.assertEquals( "()*()", preprocessor.process("[][]").toString());
Assert.assertEquals( "()*(1)", preprocessor.process("[][1]").toString()); Assert.assertEquals( "()*(1)", preprocessor.process("[][1]").toString());
Assert.assertEquals( "(0)*(1)", preprocessor.process("[0][1]").toString()); Assert.assertEquals( "(0)*(1)", preprocessor.process("[0][1]").toString());
Assert.assertEquals( "(0)*(1*10^)", preprocessor.process("[0][1E]").toString()); Assert.assertEquals( "(0)*(1E)", preprocessor.process("[0][1E]").toString());
Assert.assertEquals( "(0)*(1*10^1)", preprocessor.process("[0][1E1]").toString()); Assert.assertEquals( "(0)*(1E1)", preprocessor.process("[0][1E1]").toString());
Assert.assertEquals( "(0)*(1*10^-1)", preprocessor.process("[0][1E-1]").toString()); Assert.assertEquals( "(0)*(1E-1)", preprocessor.process("[0][1E-1]").toString());
Assert.assertEquals( "(0)*(1.*10^-1)", preprocessor.process("[0][1.E-1]").toString()); Assert.assertEquals( "(0)*(1.E-1)", preprocessor.process("[0][1.E-1]").toString());
Assert.assertEquals( "(0)*(2*10^-1)", preprocessor.process("[0][2*E-1]").toString()); Assert.assertEquals( "(0)*(2*E-1)", preprocessor.process("[0][2*E-1]").toString());
Assert.assertEquals( "(0)*ln(1)*(2*10^-1)", preprocessor.process("[0]ln(1)[2*E-1]").toString()); Assert.assertEquals( "(0)*ln(1)*(2*E-1)", preprocessor.process("[0]ln(1)[2*E-1]").toString());
Assert.assertEquals( "sin(4)*asin(0.5)*√(2)", preprocessor.process("sin(4)asin(0.5)√(2)").toString()); Assert.assertEquals( "sin(4)*asin(0.5)*√(2)", preprocessor.process("sin(4)asin(0.5)√(2)").toString());
Assert.assertEquals( "sin(4)*cos(5)", preprocessor.process("sin(4)cos(5)").toString()); Assert.assertEquals( "sin(4)*cos(5)", preprocessor.process("sin(4)cos(5)").toString());
Assert.assertEquals( "π*sin(4)*π*cos(√(5))", preprocessor.process("πsin(4)πcos(√(5))").toString()); Assert.assertEquals( "π*sin(4)*π*cos(√(5))", preprocessor.process("πsin(4)πcos(√(5))").toString());
@ -50,14 +50,15 @@ public class ToJsclTextProcessorTest {
Assert.assertEquals( "π*sin(4)+π*cos(√(5+(√(-1))))", preprocessor.process("πsin(4)+πcos(√(5+i))").toString()); Assert.assertEquals( "π*sin(4)+π*cos(√(5+(√(-1))))", preprocessor.process("πsin(4)+πcos(√(5+i))").toString());
Assert.assertEquals( "π*sin(4.01)+π*cos(√(5+(√(-1))))", preprocessor.process("πsin(4.01)+πcos(√(5+i))").toString()); Assert.assertEquals( "π*sin(4.01)+π*cos(√(5+(√(-1))))", preprocessor.process("πsin(4.01)+πcos(√(5+i))").toString());
Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))").toString()); Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))").toString());
Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))*10^2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E2").toString()); Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))E2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E2").toString());
Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))*10^-2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E-2").toString()); Assert.assertEquals( "e^π*sin(4.01)+π*cos(√(5+(√(-1))))E-2", preprocessor.process("e^πsin(4.01)+πcos(√(5+i))E-2").toString());
Assert.assertEquals( "10^2", preprocessor.process("E2").toString()); Assert.assertEquals( "E2", preprocessor.process("E2").toString());
Assert.assertEquals( "10^-2", preprocessor.process("E-2").toString()); Assert.assertEquals( "E-2", preprocessor.process("E-2").toString());
Assert.assertEquals( "10^-1/2", preprocessor.process("E-1/2").toString()); Assert.assertEquals( "E-1/2", preprocessor.process("E-1/2").toString());
Assert.assertEquals( "10^-1.2", preprocessor.process("E-1.2").toString()); Assert.assertEquals( "E-1.2", preprocessor.process("E-1.2").toString());
Assert.assertEquals( "10^(-1.2)", preprocessor.process("E(-1.2)").toString()); Assert.assertEquals( "E+1.2", preprocessor.process("E+1.2").toString());
Assert.assertEquals( "10^10^", preprocessor.process("EE").toString()); Assert.assertEquals( "E(-1.2)", preprocessor.process("E(-1.2)").toString());
Assert.assertEquals( "EE", preprocessor.process("EE").toString());
try { try {
preprocessor.process("ln()"); preprocessor.process("ln()");
Assert.fail(); Assert.fail();