number formatting + fixes

This commit is contained in:
Sergey Solovyev 2011-12-15 15:56:32 +04:00
parent 23d6973194
commit 10a367a05a
11 changed files with 222 additions and 139 deletions

View File

@ -35,7 +35,7 @@ public class CalculatorDisplay extends AutoResizeTextView {
private JsclOperation jsclOperation = JsclOperation.numeric;
@NotNull
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, true, CalculatorEngine.instance.getEngine());
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine());
@Nullable
private Generic genericResult;

View File

@ -31,7 +31,7 @@ public class CalculatorEditor extends EditText implements SharedPreferences.OnSh
private boolean highlightText = true;
@NotNull
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorEngine.instance.getEngine());
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, true, CalculatorEngine.instance.getEngine());
public CalculatorEditor(Context context) {
super(context);

View File

@ -10,8 +10,9 @@ import jscl.MathContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.android.calculator.model.NumberBuilder;
import org.solovyev.android.calculator.model.CalculatorEngine;
import org.solovyev.android.calculator.model.CalculatorParseException;
import org.solovyev.android.calculator.model.NumberBuilder;
import org.solovyev.android.calculator.model.TextProcessor;
import org.solovyev.common.utils.MutableObject;
@ -74,11 +75,11 @@ public class TextHighlighter implements TextProcessor<TextHighlighter.Result, St
private final int colorRed;
private final int colorGreen;
private final int colorBlue;
private final boolean simpleFormat;
private final boolean allowScientificFormat;
public TextHighlighter(int baseColor, boolean simpleFormat, @NotNull MathContext mathContext) {
public TextHighlighter(int baseColor, boolean allowScientificFormat, @NotNull MathContext mathContext) {
this.color = baseColor;
this.simpleFormat = simpleFormat;
this.allowScientificFormat = allowScientificFormat;
this.mathContext = mathContext;
//this.colorRed = Color.red(baseColor);
this.colorRed = (baseColor >> 16) & 0xFF;
@ -100,7 +101,7 @@ public class TextHighlighter implements TextProcessor<TextHighlighter.Result, St
int numberOffset = 0;
final NumberBuilder numberBuilder = new NumberBuilder(simpleFormat, mathContext.getNumeralBase());
final NumberBuilder numberBuilder = new NumberBuilder(allowScientificFormat, CalculatorEngine.instance.getEngine());
for (int i = 0; i < text.length(); i++) {
MathType.Result mathType = MathType.getType(text, i, numberBuilder.isHexMode());
@ -144,7 +145,7 @@ public class TextHighlighter implements TextProcessor<TextHighlighter.Result, St
}
final MutableObject<Integer> localNumberOffset = new MutableObject<Integer>(0);
numberBuilder.process(text1, localNumberOffset);
numberBuilder.processNumber(text1, localNumberOffset);
numberOffset += localNumberOffset.getObject();
if (maxNumberOfOpenGroupSymbols > 0) {

View File

@ -21,7 +21,7 @@ import java.util.*;
public enum MathType {
numeral_base(50, true, false) {
numeral_base(50, true, false, MathGroupType.number) {
private final List<String> tokens = new ArrayList<String>(10);
{
@ -40,23 +40,23 @@ public enum MathType {
}
},
dot(200, true, true, ".") {
dot(200, true, true, MathGroupType.number, ".") {
@Override
public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != digit;
}
},
grouping_separator(250, false, false, "'", " "){
grouping_separator(250, false, false, MathGroupType.number, "'", " "){
@Override
public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) throws CalculatorParseException {
return i;
}
},
power_10(300, false, false, "E"),
power_10(300, false, false, MathGroupType.number, "E"),
postfix_function(400, false, true) {
postfix_function(400, false, true, MathGroupType.function) {
@NotNull
@Override
public List<String> getTokens() {
@ -64,8 +64,8 @@ public enum MathType {
}
},
unary_operation(500, false, false, "-", "="),
binary_operation(600, false, false, "-", "+", "*", "×", "", "/", "^") {
unary_operation(500, false, false, MathGroupType.operation, "-", "="),
binary_operation(600, false, false, MathGroupType.operation, "-", "+", "*", "×", "", "/", "^") {
@Override
protected String getSubstituteToJscl(@NotNull String match) {
if (match.equals("×") || match.equals("")) {
@ -76,7 +76,7 @@ public enum MathType {
}
},
open_group_symbol(800, true, false, "[", "(", "{") {
open_group_symbol(800, true, false, MathGroupType.other, "[", "(", "{") {
@Override
public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != function && mathTypeBefore != operator;
@ -88,7 +88,7 @@ public enum MathType {
}
},
close_group_symbol(900, false, true, "]", ")", "}") {
close_group_symbol(900, false, true, MathGroupType.other, "]", ")", "}") {
@Override
public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
return false;
@ -100,7 +100,7 @@ public enum MathType {
}
},
function(1000, true, true) {
function(1000, true, true, MathGroupType.function) {
@NotNull
@Override
public List<String> getTokens() {
@ -108,7 +108,7 @@ public enum MathType {
}
},
operator(1050, true, true) {
operator(1050, true, true, MathGroupType.function) {
@NotNull
@Override
public List<String> getTokens() {
@ -116,7 +116,7 @@ public enum MathType {
}
},
constant(1100, true, true) {
constant(1100, true, true, MathGroupType.other) {
@NotNull
@Override
public List<String> getTokens() {
@ -129,7 +129,7 @@ public enum MathType {
}
},
digit(1125, true, true) {
digit(1125, true, true, MathGroupType.number) {
private final List<String> tokens = new ArrayList<String>(16);
{
@ -149,9 +149,9 @@ public enum MathType {
}
},
comma(1150, false, false, ","),
comma(1150, false, false, MathGroupType.other, ","),
text(1200, false, false) {
text(1200, false, false, MathGroupType.other) {
@Override
public int processToJscl(@NotNull StringBuilder result, int i, @NotNull String match) {
if (match.length() > 0) {
@ -169,6 +169,13 @@ public enum MathType {
}
};
public static enum MathGroupType {
function,
number,
operation,
other
}
@NotNull
private final List<String> tokens;
@ -179,23 +186,34 @@ public enum MathType {
private final boolean needMultiplicationSignAfter;
@NotNull
private final MathGroupType groupType;
MathType(@NotNull Integer priority,
boolean needMultiplicationSignBefore,
boolean needMultiplicationSignAfter,
@NotNull MathGroupType groupType,
@NotNull String... tokens) {
this(priority, needMultiplicationSignBefore, needMultiplicationSignAfter, CollectionsUtils.asList(tokens));
this(priority, needMultiplicationSignBefore, needMultiplicationSignAfter, groupType, CollectionsUtils.asList(tokens));
}
MathType(@NotNull Integer priority,
boolean needMultiplicationSignBefore,
boolean needMultiplicationSignAfter,
@NotNull MathGroupType groupType,
@NotNull List<String> tokens) {
this.priority = priority;
this.needMultiplicationSignBefore = needMultiplicationSignBefore;
this.needMultiplicationSignAfter = needMultiplicationSignAfter;
this.groupType = groupType;
this.tokens = Collections.unmodifiableList(tokens);
}
@NotNull
public MathGroupType getGroupType() {
return groupType;
}
/* public static int getPostfixFunctionStart(@NotNull CharSequence s, int position) throws ParseException {
assert s.length() > position;

View File

@ -169,7 +169,7 @@ public enum CalculatorEngine {
calculationResult.setObject(genericResult);
} catch (AbstractJsclArithmeticException e) {
evalException.setObject(new CalculatorEvalException(e, jsclExpression));
evalException.setObject(new CalculatorEvalException(e, e, jsclExpression));
} catch (ArithmeticException e) {
//System.out.println(e.getMessage());
parseException.setObject(new CalculatorParseException(Messages.msg_1, jsclExpression, e.getMessage()));
@ -207,7 +207,8 @@ public enum CalculatorEngine {
}
if (parseExceptionObject != null || evalExceptionObject != null) {
if (finalOperation == JsclOperation.numeric && preparedExpression.isExistsUndefinedVar()) {
if (finalOperation == JsclOperation.numeric &&
( preparedExpression.isExistsUndefinedVar() || ( evalExceptionObject != null && evalExceptionObject.getCause() instanceof NumeralBaseException)) ) {
return evaluate(JsclOperation.simplify, expression, mr);
}

View File

@ -6,6 +6,7 @@
package org.solovyev.android.calculator.model;
import jscl.AbstractJsclArithmeticException;
import org.jetbrains.annotations.NotNull;
import org.solovyev.common.exceptions.SersoException;
import org.solovyev.common.msg.Message;
@ -27,7 +28,8 @@ public class CalculatorEvalException extends SersoException implements Message {
@NotNull
private final String expression;
public CalculatorEvalException(@NotNull Message message, String expression) {
public CalculatorEvalException(@NotNull Message message, @NotNull Throwable cause, String expression) {
super(cause);
this.message = message;
this.expression = expression;
}

View File

@ -33,16 +33,16 @@ public class FromJsclSimplifyTextProcessor implements TextProcessor<String, Gene
public String process(@NotNull String s) {
final StringBuilder sb = new StringBuilder();
final NumberBuilder numberBuilder = new NumberBuilder(true, mathContext.getNumeralBase());
final NumberBuilder nb = new NumberBuilder(false, CalculatorEngine.instance.getEngine());
for (int i = 0; i < s.length(); i++) {
final MathType.Result mathTypeResult = MathType.getType(s, i, numberBuilder.isHexMode());
final MathType.Result mathTypeResult = MathType.getType(s, i, nb.isHexMode());
numberBuilder.process(sb, mathTypeResult, null);
nb.process(sb, mathTypeResult, null);
i = mathTypeResult.processFromJscl(sb, i);
}
numberBuilder.process(sb, null);
nb.processNumber(sb, null);
return removeMultiplicationSigns(sb.toString());
}

View File

@ -6,9 +6,10 @@
package org.solovyev.android.calculator.model;
import jscl.MathContext;
import jscl.MathEngine;
import jscl.NumeralBase;
import jscl.math.numeric.Numeric;
import jscl.math.function.IConstant;
import jscl.math.numeric.Real;
import jscl.text.*;
import org.jetbrains.annotations.NotNull;
@ -28,50 +29,70 @@ import java.util.List;
*/
public class NumberBuilder {
@NotNull
private final MathEngine engine;
@Nullable
private StringBuilder numberBuilder = null;
@Nullable
private String number = null;
private final boolean simpleFormat;
@NotNull
private final NumeralBase defaultNumeralBase;
private final boolean allowScientificFormat;
@Nullable
private NumeralBase nb;
public NumberBuilder(boolean simpleFormat, @NotNull NumeralBase defaultNumeralBase) {
this.simpleFormat = simpleFormat;
this.defaultNumeralBase = defaultNumeralBase;
this.nb = defaultNumeralBase;
public NumberBuilder(boolean allowScientificFormat, @NotNull MathEngine engine) {
this.allowScientificFormat = allowScientificFormat;
this.nb = engine.getNumeralBase();
this.engine = engine;
}
/**
* Method replaces number in text according to some rules (e.g. formatting)
*
* @param text text where number can be replaced
* @param mathTypeResult math type result of current token
* @param offset offset between new number length and old number length (newNumberLength - oldNumberLength)
*
*
* @return new math type result (as one can be changed due to substituting of number with constant)
*/
@NotNull
public MathType.Result process(@NotNull StringBuilder sb, @NotNull MathType.Result mathTypeResult, @Nullable MutableObject<Integer> numberOffset) {
number = null;
public MathType.Result process(@NotNull StringBuilder text, @NotNull MathType.Result mathTypeResult, @Nullable MutableObject<Integer> offset) {
final MathType.Result possibleResult;
if ((CollectionsUtils.contains(mathTypeResult.getMathType(), MathType.digit, MathType.numeral_base, MathType.dot, MathType.grouping_separator, MathType.power_10) ||
isSignAfterE(mathTypeResult)) && numeralBaseCheck(mathTypeResult) && numeralBaseInTheStart(mathTypeResult.getMathType())) {
if (canContinue(mathTypeResult)) {
// let's continue building number
if (numberBuilder == null) {
// if new number => create new builder
numberBuilder = new StringBuilder();
}
if (mathTypeResult.getMathType() != MathType.numeral_base) {
// just add matching string
numberBuilder.append(mathTypeResult.getMatch());
} else {
// set explicitly numeral base (do not include it into number)
nb = NumeralBase.getByPrefix(mathTypeResult.getMatch());
}
possibleResult = null;
} else {
possibleResult = process(sb, numberOffset);
// process current number (and go to the next one)
possibleResult = processNumber(text, offset);
}
return possibleResult == null ? mathTypeResult : possibleResult;
}
/**
* Method determines if we can continue to process current number
* @param mathTypeResult current math type result
*
* @return true if we can continue of processing of current number, if false - new number should be constructed
*/
private boolean canContinue(@NotNull MathType.Result mathTypeResult) {
return ((mathTypeResult.getMathType().getGroupType() == MathType.MathGroupType.number && numeralBaseCheck(mathTypeResult) && numeralBaseInTheStart(mathTypeResult.getMathType()) || isSignAfterE(mathTypeResult)));
}
private boolean numeralBaseInTheStart(@NotNull MathType mathType) {
return mathType != MathType.numeral_base || numberBuilder == null;
}
@ -104,101 +125,92 @@ public class NumberBuilder {
return false;
}
/**
* Method replaces number in text according to some rules (e.g. formatting)
*
* @param text text where number can be replaced
* @param offset offset between new number length and old number length (newNumberLength - oldNumberLength)
*
* @return new math type result (as one can be changed due to substituting of number with constant)
*/
@Nullable
public MathType.Result process(@NotNull StringBuilder sb, @Nullable MutableObject<Integer> numberOffset) {
int numberOfTokens = 0;
public MathType.Result processNumber(@NotNull StringBuilder text, @Nullable MutableObject<Integer> offset) {
// total number of trimmed chars
int trimmedChars = 0;
String number = null;
// save numeral base (as later it might be replaced)
final NumeralBase localNb = getNumeralBase();
final NumeralBase localNb;
if (numberBuilder != null) {
try {
number = numberBuilder.toString();
List<String> tokens = new ArrayList<String>();
// let's get rid of unnecessary characters (grouping separators, + after E)
final List<String> tokens = new ArrayList<String>();
tokens.addAll(MathType.grouping_separator.getTokens());
// + after E can be omitted: 10+E = 10E (NOTE: - cannot be omitted )
tokens.add("+");
for (String groupingSeparator : tokens) {
String newNumber = number.replace(groupingSeparator, "");
numberOfTokens += number.length() - newNumber.length();
number = newNumber;
final String trimmedNumber = number.replace(groupingSeparator, "");
trimmedChars += number.length() - trimmedNumber.length();
number = trimmedNumber;
}
toDouble(number, getNumeralBase());
// check if number still valid
toDouble(number, getNumeralBase(), engine);
} catch (NumberFormatException e) {
// number is not valid => stop
number = null;
}
numberBuilder = null;
localNb = getNumeralBase();
nb = defaultNumeralBase;
} else {
number = null;
localNb = getNumeralBase();
// must set default numeral base (exit numeral base mode)
nb = engine.getNumeralBase();
}
return replaceSystemVars(sb, number, numberOfTokens, numberOffset, localNb, simpleFormat);
return replaceNumberInText(text, number, trimmedChars, offset, localNb, allowScientificFormat, engine);
}
@Nullable
private static MathType.Result replaceSystemVars(StringBuilder sb, String number, int numberOfTokens, @Nullable MutableObject<Integer> numberOffset, @NotNull NumeralBase nb, boolean simpleFormat) {
private static MathType.Result replaceNumberInText(@NotNull StringBuilder text,
@Nullable String number,
int trimmedChars,
@Nullable MutableObject<Integer> offset,
@NotNull NumeralBase nb,
boolean allowScientificFormat,
@NotNull final MathEngine engine) {
MathType.Result result = null;
if (number != null) {
final String finalNumber = number;
final Var var = CollectionsUtils.find(CalculatorEngine.instance.getVarsRegister().getSystemEntities(), new Finder<Var>() {
// detect if current number is precisely equals to constant in constants' registry (NOTE: ONLY FOR SYSTEM CONSTANTS)
final IConstant constant = CollectionsUtils.find(engine.getConstantsRegistry().getSystemEntities(), new Finder<IConstant>() {
@Override
public boolean isFound(@Nullable Var var) {
return var != null && finalNumber.equals(var.getValue());
public boolean isFound(@Nullable IConstant constant) {
return constant != null && finalNumber.equals(constant.getValue());
}
});
if (var != null) {
sb.delete(sb.length() - number.length() - numberOfTokens, sb.length());
sb.append(var.getName());
result = new MathType.Result(MathType.constant, var.getName());
} else {
sb.delete(sb.length() - number.length() - numberOfTokens, sb.length());
// in any case remove old number from text
final int oldNumberLength = number.length() + trimmedChars;
text.delete(text.length() - oldNumberLength, text.length());
final String formattedNumber;
if (!simpleFormat) {
int indexOfDot = number.indexOf('.');
if (indexOfDot < 0) {
int indexOfE;
if (nb == NumeralBase.hex) {
indexOfE = -1;
if (constant != null) {
// let's change number with constant from registry
text.append(constant.getName());
result = new MathType.Result(MathType.constant, constant.getName());
} else {
indexOfE = number.indexOf('E');
final String newNumber = formatNumber(number, nb, allowScientificFormat, engine);
if (offset != null) {
// register offset between old number and new number
offset.setObject(newNumber.length() - oldNumberLength);
}
if (indexOfE < 0) {
formattedNumber = toString(toDouble(number, nb), nb);
} else {
final String part;
if (indexOfDot != 0) {
part = toString(toDouble(number.substring(0, indexOfE), nb), nb);
} else {
part = "";
}
formattedNumber = part + number.substring(indexOfE);
}
} else {
final String integerPart;
if (indexOfDot != 0) {
integerPart = toString(toDouble(number.substring(0, indexOfDot), nb), nb);
} else {
integerPart = "";
}
formattedNumber = integerPart + number.substring(indexOfDot);
}
} else {
formattedNumber = toString(toDouble(number, nb), nb);
}
if (numberOffset != null) {
numberOffset.setObject(formattedNumber.length() - number.length() - numberOfTokens);
}
sb.append(formattedNumber);
text.append(newNumber);
}
}
@ -206,40 +218,78 @@ public class NumberBuilder {
}
@NotNull
private static String toString(@NotNull Double value, @NotNull NumeralBase nb) {
return CalculatorEngine.instance.getEngine().format(value, nb);
private static String formatNumber(@NotNull String number, @NotNull NumeralBase nb, boolean allowScientificFormat, @NotNull MathEngine engine) {
String result;
if (allowScientificFormat) {
int indexOfDot = number.indexOf('.');
if (indexOfDot < 0) {
int indexOfE;
if (nb == NumeralBase.hex) {
indexOfE = -1;
} else {
indexOfE = number.indexOf(MathType.POWER_10);
}
if (indexOfE < 0) {
result = toString(number, nb, engine);
} else {
final String part;
if (indexOfDot != 0) {
part = toString(number.substring(0, indexOfE), nb, engine);
} else {
part = "";
}
result = part + number.substring(indexOfE);
}
} else {
final String integerPart;
if (indexOfDot != 0) {
integerPart = toString(number.substring(0, indexOfDot), nb, engine);
} else {
integerPart = "";
}
result = integerPart + number.substring(indexOfDot);
}
} else {
result = toString(number, nb, engine);
}
return result;
}
@NotNull
private static String toString(@NotNull String value, @NotNull NumeralBase nb, @NotNull MathContext mathContext) {
return mathContext.format(toDouble(value, nb, mathContext), nb);
}
public boolean isHexMode() {
return nb == NumeralBase.hex || ( nb == null && defaultNumeralBase == NumeralBase.hex);
return nb == NumeralBase.hex || (nb == null && engine.getNumeralBase() == NumeralBase.hex);
}
@NotNull
private NumeralBase getNumeralBase() {
return nb == null ? defaultNumeralBase : nb;
return nb == null ? engine.getNumeralBase() : nb;
}
@NotNull
private static Double toDouble(@NotNull String s, @NotNull NumeralBase nb) throws NumberFormatException{
final MathEngine me = CalculatorEngine.instance.getEngine();
final NumeralBase defaultNb = me.getNumeralBase();
private static Double toDouble(@NotNull String s, @NotNull NumeralBase nb, @NotNull final MathContext mc) throws NumberFormatException {
final NumeralBase defaultNb = mc.getNumeralBase();
try {
me.setNumeralBase(nb);
mc.setNumeralBase(nb);
try {
return JsclIntegerParser.parser.parse(Parser.Parameters.newInstance(s, new MutableInt(0), me), null).content().doubleValue();
return JsclIntegerParser.parser.parse(Parser.Parameters.newInstance(s, new MutableInt(0), mc), null).content().doubleValue();
} catch (ParseException e) {
try {
return ((Real) DoubleParser.parser.parse(Parser.Parameters.newInstance(s, new MutableInt(0), me), null).content()).doubleValue();
return ((Real) DoubleParser.parser.parse(Parser.Parameters.newInstance(s, new MutableInt(0), mc), null).content()).doubleValue();
} catch (ParseException e1) {
throw new NumberFormatException();
}
}
} finally {
me.setNumeralBase(defaultNb);
mc.setNumeralBase(defaultNb);
}
}
}

View File

@ -6,7 +6,6 @@
package org.solovyev.android.calculator.model;
import jscl.JsclMathEngine;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.StartsWithFinder;
import org.solovyev.android.calculator.jscl.JsclOperation;
@ -41,7 +40,7 @@ class ToJsclTextProcessor implements TextProcessor<PreparedExpression, String> {
final StringBuilder sb = new StringBuilder(s);
final NumberBuilder nb = new NumberBuilder(true, CalculatorEngine.instance.getEngine().getNumeralBase());
final NumberBuilder nb = new NumberBuilder(false, CalculatorEngine.instance.getEngine());
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ' ') continue;
startsWithFinder.setI(i);

View File

@ -26,7 +26,7 @@ public class TextHighlighterTest {
@Test
public void testProcess() throws Exception {
TextProcessor<?, String> textHighlighter = new TextHighlighter(0, true, JsclMathEngine.instance);
TextProcessor<?, String> textHighlighter = new TextHighlighter(0, false, JsclMathEngine.instance);
final Random random = new Random(new Date().getTime());
for (int i = 0; i < 1000; i++) {
@ -48,7 +48,7 @@ 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, JsclMathEngine.instance);
textHighlighter = new TextHighlighter(0, true, JsclMathEngine.instance);
Assert.assertEquals("0.1E3", textHighlighter.process("0.1E3").toString());
Assert.assertEquals("1E3", textHighlighter.process("1E3").toString());
Assert.assertEquals("2<b>0x:</b>", textHighlighter.process("20x:").toString());
@ -60,7 +60,7 @@ public class TextHighlighterTest {
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, JsclMathEngine.instance);
textHighlighter = new TextHighlighter(0, false, JsclMathEngine.instance);
textHighlighter.process("cannot calculate 3^10^10 !!!\n" +
" unable to enter 0. FIXED\n" +

View File

@ -183,6 +183,18 @@ public class CalculatorEngineTest {
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("0.933", cm.evaluate(JsclOperation.numeric, "0x:E/0x:F").getResult());
try {
cm.getEngine().setNumeralBase(NumeralBase.hex);
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.numeric, "0x:E/0x:F").getResult());
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.simplify, "0x:E/0x:F").getResult());
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.numeric, "E/F").getResult());
Assert.assertEquals("E/F", cm.evaluate(JsclOperation.simplify, "E/F").getResult());
} finally {
cm.getEngine().setNumeralBase(NumeralBase.dec);
}
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((0))))))").getResult());
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))").getResult());