rounding fix + color display + refactor
This commit is contained in:
parent
6f4eaec0d4
commit
029a3b649a
@ -6,8 +6,14 @@
|
|||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.text.Html;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.solovyev.android.calculator.model.ParseException;
|
||||||
|
import org.solovyev.android.calculator.model.TextProcessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: serso
|
* User: serso
|
||||||
@ -18,6 +24,9 @@ public class CalculatorDisplay extends TextView {
|
|||||||
|
|
||||||
private boolean valid = true;
|
private boolean valid = true;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final static TextProcessor<String> textHighlighter = new TextHighlighter(Color.WHITE);
|
||||||
|
|
||||||
public CalculatorDisplay(Context context) {
|
public CalculatorDisplay(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
@ -44,4 +53,22 @@ public class CalculatorDisplay extends TextView {
|
|||||||
|
|
||||||
setValid(true);
|
setValid(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized void redraw() {
|
||||||
|
if (isValid()) {
|
||||||
|
String text = getText().toString();
|
||||||
|
|
||||||
|
Log.d(this.getClass().getName(), text);
|
||||||
|
|
||||||
|
try {
|
||||||
|
text = textHighlighter.process(text);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
Log.e(this.getClass().getName(), e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(this.getClass().getName(), text);
|
||||||
|
super.setText(Html.fromHtml(text), BufferType.EDITABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -171,19 +171,20 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void evaluate(@Nullable final String expression) {
|
private void evaluate(@Nullable final String expression) {
|
||||||
final CalculatorDisplay localDisplay = display;
|
|
||||||
if (!StringUtils.isEmpty(expression)) {
|
if (!StringUtils.isEmpty(expression)) {
|
||||||
try {
|
try {
|
||||||
Log.d(CalculatorModel.class.getName(), "Trying to evaluate: " + expression /*+ StringUtils.fromStackTrace(Thread.currentThread().getStackTrace())*/);
|
Log.d(CalculatorModel.class.getName(), "Trying to evaluate: " + expression /*+ StringUtils.fromStackTrace(Thread.currentThread().getStackTrace())*/);
|
||||||
localDisplay.setText(calculatorEngine.evaluate(JsclOperation.numeric, expression));
|
display.setText(calculatorEngine.evaluate(JsclOperation.numeric, expression));
|
||||||
} catch (EvalError e) {
|
} catch (EvalError e) {
|
||||||
handleEvaluationException(expression, localDisplay, e);
|
handleEvaluationException(expression, display, e);
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
handleEvaluationException(expression, localDisplay, e);
|
handleEvaluationException(expression, display, e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
localDisplay.setText("");
|
this.display.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.display.redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleEvaluationException(@NotNull String expression, @NotNull CalculatorDisplay localDisplay, @NotNull Exception e) {
|
private void handleEvaluationException(@NotNull String expression, @NotNull CalculatorDisplay localDisplay, @NotNull Exception e) {
|
||||||
@ -212,15 +213,19 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
|||||||
final MathType.Result mathType = MathType.getType(text, 0);
|
final MathType.Result mathType = MathType.getType(text, 0);
|
||||||
|
|
||||||
int cursorPositionOffset = 0;
|
int cursorPositionOffset = 0;
|
||||||
|
|
||||||
final StringBuilder textToBeInserted = new StringBuilder(text);
|
final StringBuilder textToBeInserted = new StringBuilder(text);
|
||||||
switch (mathType.getMathType()) {
|
switch (mathType.getMathType()) {
|
||||||
case function:
|
case function:
|
||||||
textToBeInserted.append("()");
|
textToBeInserted.append("()");
|
||||||
cursorPositionOffset = -1;
|
cursorPositionOffset = -1;
|
||||||
break;
|
break;
|
||||||
case group_symbols:
|
}
|
||||||
|
|
||||||
|
if (cursorPositionOffset == 0) {
|
||||||
|
if ( MathType.openGroupSymbols.contains(text) ) {
|
||||||
cursorPositionOffset = -1;
|
cursorPositionOffset = -1;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.getText().insert(editor.getSelectionStart(), textToBeInserted.toString());
|
editor.getText().insert(editor.getSelectionStart(), textToBeInserted.toString());
|
||||||
@ -256,6 +261,7 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
|
|||||||
setValuesFromHistory(this.display, editorHistoryState.getDisplayState());
|
setValuesFromHistory(this.display, editorHistoryState.getDisplayState());
|
||||||
|
|
||||||
editor.redraw();
|
editor.redraw();
|
||||||
|
display.redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,15 +97,15 @@ public class TextHighlighter implements TextProcessor<String> {
|
|||||||
for (; i < s.length(); i++) {
|
for (; i < s.length(); i++) {
|
||||||
char ch = s.charAt(i);
|
char ch = s.charAt(i);
|
||||||
|
|
||||||
if (MathType.openGroupSymbols.contains(ch)) {
|
if (MathType.open_group_symbol.getTokens().contains(String.valueOf(ch))) {
|
||||||
result.append(ch);
|
result.append(ch);
|
||||||
result.append("</font>");
|
result.append("</font>");
|
||||||
i = processBracketGroup(result, s, i + 1, numberOfOpenings + 1, maxNumberOfGroups);
|
i = processBracketGroup(result, s, i + 1, numberOfOpenings + 1, maxNumberOfGroups);
|
||||||
result.append("<font color=\"").append(getColor(maxNumberOfGroups, numberOfOpenings)).append("\">");
|
result.append("<font color=\"").append(getColor(maxNumberOfGroups, numberOfOpenings)).append("\">");
|
||||||
if (i < s.length() && MathType.closeGroupSymbols.contains(s.charAt(i))) {
|
if (i < s.length() && MathType.close_group_symbol.getTokens().contains(String.valueOf(s.charAt(i)))) {
|
||||||
result.append(s.charAt(i));
|
result.append(s.charAt(i));
|
||||||
}
|
}
|
||||||
} else if (MathType.closeGroupSymbols.contains(ch)) {
|
} else if (MathType.close_group_symbol.getTokens().contains(String.valueOf(ch))) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
result.append(ch);
|
result.append(ch);
|
||||||
|
@ -7,12 +7,14 @@
|
|||||||
package org.solovyev.android.calculator.jscl;
|
package org.solovyev.android.calculator.jscl;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.solovyev.android.calculator.math.MathType;
|
import org.solovyev.android.calculator.math.MathType;
|
||||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||||
import org.solovyev.android.calculator.model.ParseException;
|
import org.solovyev.android.calculator.model.ParseException;
|
||||||
import org.solovyev.android.calculator.model.TextProcessor;
|
import org.solovyev.android.calculator.model.TextProcessor;
|
||||||
import org.solovyev.common.utils.MathUtils;
|
|
||||||
import org.solovyev.util.math.Complex;
|
import java.math.BigDecimal;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: serso
|
* User: serso
|
||||||
@ -25,11 +27,12 @@ class FromJsclNumericTextProcessor implements TextProcessor<String> {
|
|||||||
@Override
|
@Override
|
||||||
public String process(@NotNull String result) throws ParseException {
|
public String process(@NotNull String result) throws ParseException {
|
||||||
try {
|
try {
|
||||||
final Double roundedValue = round(result);
|
final Double doubleValue = Double.valueOf(result);
|
||||||
if ( roundedValue.isInfinite() ) {
|
|
||||||
|
if (doubleValue.isInfinite()) {
|
||||||
result = MathType.INFINITY;
|
result = MathType.INFINITY;
|
||||||
} else {
|
} else {
|
||||||
result = String.valueOf(roundedValue);
|
result = format(doubleValue);
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
result = result.replace(MathType.INFINITY_JSCL, MathType.INFINITY);
|
result = result.replace(MathType.INFINITY_JSCL, MathType.INFINITY);
|
||||||
@ -49,6 +52,21 @@ class FromJsclNumericTextProcessor implements TextProcessor<String> {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String format(@NotNull String value) {
|
||||||
|
return format(Double.valueOf(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String format(@NotNull Double value) {
|
||||||
|
if (!value.isInfinite() && !value.isNaN()) {
|
||||||
|
final DecimalFormat df = new DecimalFormat();
|
||||||
|
df.setGroupingUsed(false);
|
||||||
|
df.setMaximumFractionDigits(CalculatorEngine.instance.getPrecision());
|
||||||
|
return df.format(new BigDecimal(value).setScale(CalculatorEngine.instance.getPrecision(), BigDecimal.ROUND_HALF_UP).doubleValue());
|
||||||
|
} else {
|
||||||
|
return String.valueOf(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected String createResultForComplexNumber(@NotNull final String s) {
|
protected String createResultForComplexNumber(@NotNull final String s) {
|
||||||
final Complex complex = new Complex();
|
final Complex complex = new Complex();
|
||||||
|
|
||||||
@ -56,13 +74,13 @@ class FromJsclNumericTextProcessor implements TextProcessor<String> {
|
|||||||
// may be it's just complex number
|
// may be it's just complex number
|
||||||
int plusIndex = s.lastIndexOf("+");
|
int plusIndex = s.lastIndexOf("+");
|
||||||
if (plusIndex >= 0) {
|
if (plusIndex >= 0) {
|
||||||
complex.setReal(round(s.substring(0, plusIndex)));
|
complex.setReal(format(s.substring(0, plusIndex)));
|
||||||
result += complex.getReal();
|
result += complex.getReal();
|
||||||
result += "+";
|
result += "+";
|
||||||
} else {
|
} else {
|
||||||
plusIndex = s.lastIndexOf("-");
|
plusIndex = s.lastIndexOf("-");
|
||||||
if (plusIndex >= 0) {
|
if (plusIndex >= 0) {
|
||||||
complex.setReal(round(s.substring(0, plusIndex)));
|
complex.setReal(format(s.substring(0, plusIndex)));
|
||||||
result += complex.getReal();
|
result += complex.getReal();
|
||||||
result += "-";
|
result += "-";
|
||||||
}
|
}
|
||||||
@ -71,7 +89,7 @@ class FromJsclNumericTextProcessor implements TextProcessor<String> {
|
|||||||
|
|
||||||
int multiplyIndex = s.indexOf("*");
|
int multiplyIndex = s.indexOf("*");
|
||||||
if (multiplyIndex >= 0) {
|
if (multiplyIndex >= 0) {
|
||||||
complex.setImaginary(round(s.substring(plusIndex >= 0 ? plusIndex + 1 : 0, multiplyIndex)));
|
complex.setImaginary(format(s.substring(plusIndex >= 0 ? plusIndex + 1 : 0, multiplyIndex)));
|
||||||
result += complex.getImaginary();
|
result += complex.getImaginary();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -81,8 +99,31 @@ class FromJsclNumericTextProcessor implements TextProcessor<String> {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Double round(@NotNull String result) {
|
private class Complex {
|
||||||
final Double dResult = Double.valueOf(result);
|
|
||||||
return MathUtils.round(dResult, CalculatorEngine.instance.getNumberOfFractionDigits());
|
@Nullable
|
||||||
|
private String real;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private String imaginary;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getReal() {
|
||||||
|
return real;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setReal(@Nullable String real) {
|
||||||
|
this.real = real;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getImaginary() {
|
||||||
|
return imaginary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImaginary(@Nullable String imaginary) {
|
||||||
|
this.imaginary = imaginary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,8 @@ public class Functions {
|
|||||||
allPrefix = functions;
|
allPrefix = functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final static Character FACT = '!';
|
public final static String FACT = "!";
|
||||||
public final static Character DEGREE = '°';
|
public final static String DEGREE = "°";
|
||||||
|
|
||||||
public static final List<Character> allPostfix = Arrays.asList(FACT, DEGREE);
|
public static final List<String> allPostfix = Arrays.asList(FACT, DEGREE);
|
||||||
}
|
}
|
||||||
|
@ -9,60 +9,119 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.solovyev.android.calculator.CharacterAtPositionFinder;
|
import org.solovyev.android.calculator.CharacterAtPositionFinder;
|
||||||
import org.solovyev.android.calculator.StartsWithFinder;
|
import org.solovyev.android.calculator.StartsWithFinder;
|
||||||
import org.solovyev.android.calculator.model.CalculatorEngine;
|
import org.solovyev.android.calculator.model.CalculatorEngine;
|
||||||
|
import org.solovyev.common.utils.CollectionsUtils;
|
||||||
import org.solovyev.common.utils.Finder;
|
import org.solovyev.common.utils.Finder;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.solovyev.common.utils.CollectionsUtils.get;
|
import static org.solovyev.common.utils.CollectionsUtils.get;
|
||||||
|
|
||||||
public enum MathType {
|
public enum MathType {
|
||||||
|
|
||||||
digit,
|
digit(100, true, true, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9") {
|
||||||
dot,
|
@Override
|
||||||
power_10,
|
public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
|
||||||
constant,
|
return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != digit && mathTypeBefore != dot;
|
||||||
function,
|
}
|
||||||
postfix_function,
|
},
|
||||||
unary_operation,
|
|
||||||
binary_operation,
|
dot(200, true, true, "."){
|
||||||
group_symbols,
|
@Override
|
||||||
open_group_symbol,
|
public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
|
||||||
close_group_symbol,
|
return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != digit;
|
||||||
text;
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
power_10(300, true, false, "E"),
|
||||||
|
|
||||||
|
postfix_function(400, true, false, Functions.allPostfix),
|
||||||
|
unary_operation(500, false, false, "-", "=", "!"),
|
||||||
|
binary_operation(600, false, false, "-", "+", "*", "×", "∙", "/", "^"),
|
||||||
|
open_group_symbol(800, true, false, "[", "(", "{") {
|
||||||
|
@Override
|
||||||
|
public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
|
||||||
|
return super.isNeedMultiplicationSignBefore(mathTypeBefore) && mathTypeBefore != function;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
close_group_symbol(900, false, true, "]", ")", "}") {
|
||||||
|
@Override
|
||||||
|
public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function(1000, true, true, Functions.allPrefix),
|
||||||
|
constant(1100, true, true) {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<String> getTokens() {
|
||||||
|
return CalculatorEngine.instance.getVarsRegister().getVarNames();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
text(1200, false, false);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final List<String> tokens;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final Integer priority;
|
||||||
|
|
||||||
|
private final boolean needMultiplicationSignBefore;
|
||||||
|
|
||||||
|
private final boolean needMultiplicationSignAfter;
|
||||||
|
|
||||||
|
MathType(@NotNull Integer priority,
|
||||||
|
boolean needMultiplicationSignBefore,
|
||||||
|
boolean needMultiplicationSignAfter,
|
||||||
|
@NotNull String... tokens) {
|
||||||
|
this(priority, needMultiplicationSignBefore, needMultiplicationSignAfter, CollectionsUtils.asList(tokens));
|
||||||
|
}
|
||||||
|
|
||||||
|
MathType(@NotNull Integer priority,
|
||||||
|
boolean needMultiplicationSignBefore,
|
||||||
|
boolean needMultiplicationSignAfter,
|
||||||
|
@NotNull List<String> tokens) {
|
||||||
|
this.priority = priority;
|
||||||
|
this.needMultiplicationSignBefore = needMultiplicationSignBefore;
|
||||||
|
this.needMultiplicationSignAfter = needMultiplicationSignAfter;
|
||||||
|
this.tokens = Collections.unmodifiableList(tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<String> getTokens() {
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNeedMultiplicationSignBefore() {
|
||||||
|
return needMultiplicationSignBefore;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNeedMultiplicationSignAfter() {
|
||||||
|
return needMultiplicationSignAfter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNeedMultiplicationSignBefore(@NotNull MathType mathTypeBefore) {
|
||||||
|
return needMultiplicationSignBefore && mathTypeBefore.isNeedMultiplicationSignAfter();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 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 = "sqrt(-1)";
|
public static final String IMAGINARY_NUMBER_JSCL = "sqrt(-1)";
|
||||||
|
|
||||||
public static final String PI = "π";
|
public static final String PI = "π";
|
||||||
public static final String E = "e";
|
public static final String E = "e";
|
||||||
public final static String NAN = "NaN";
|
public final static String NAN = "NaN";
|
||||||
|
|
||||||
public final static String INFINITY = "∞";
|
public final static String INFINITY = "∞";
|
||||||
public final static String INFINITY_JSCL = "Infinity";
|
public final static String INFINITY_JSCL = "Infinity";
|
||||||
|
|
||||||
public static final List<String> constants = Arrays.asList(E, PI, IMAGINARY_NUMBER, NAN, INFINITY);
|
public static final List<String> constants = Arrays.asList(E, PI, IMAGINARY_NUMBER, NAN, INFINITY);
|
||||||
|
|
||||||
public static final List<String> digits = Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
|
|
||||||
|
|
||||||
public static final List<Character> dots = Arrays.asList('.');
|
|
||||||
|
|
||||||
|
|
||||||
public static final List<Character> unaryOperations = Arrays.asList('-', '=', '!');
|
|
||||||
|
|
||||||
public static final List<Character> binaryOperations = Arrays.asList('-', '+', '*', '×', '∙', '/', '^');
|
|
||||||
|
|
||||||
public static final List<String> prefixFunctions = Functions.allPrefix;
|
|
||||||
|
|
||||||
public static final List<Character> postfixFunctions = Functions.allPostfix;
|
|
||||||
|
|
||||||
public static final List<String> groupSymbols = Arrays.asList("[]", "()", "{}");
|
|
||||||
|
|
||||||
public static final List<Character> openGroupSymbols = Arrays.asList('[', '(', '{');
|
|
||||||
|
|
||||||
public static final List<Character> closeGroupSymbols = Arrays.asList(']', ')', '}');
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method determines mathematical entity type for text substring starting from ith index
|
* Method determines mathematical entity type for text substring starting from ith index
|
||||||
*
|
*
|
||||||
@ -80,67 +139,39 @@ public enum MathType {
|
|||||||
return new Result(MathType.text, text);
|
return new Result(MathType.text, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
final StartsWithFinder stringStartWithFinder = new StartsWithFinder(text, i);
|
final StartsWithFinder startsWithFinder = new StartsWithFinder(text, i);
|
||||||
final CharacterAtPositionFinder characterStartWithFinder = new CharacterAtPositionFinder(text, i);
|
|
||||||
|
|
||||||
String foundString = get(digits, stringStartWithFinder);
|
for (MathType mathType : getMathTypesByPriority()) {
|
||||||
if (foundString != null) {
|
final String s = get(mathType.getTokens(), startsWithFinder);
|
||||||
return new Result(MathType.digit, foundString);
|
if ( s != null ) {
|
||||||
|
return new Result(mathType, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
Character foundCharacter = get(dots, characterStartWithFinder);
|
|
||||||
if (foundCharacter != null) {
|
|
||||||
return new Result(dot, String.valueOf(foundCharacter));
|
|
||||||
}
|
|
||||||
|
|
||||||
foundCharacter = characterStartWithFinder.isFound(POWER_10) ? POWER_10 : null;
|
|
||||||
if (foundCharacter != null) {
|
|
||||||
return new Result(power_10, String.valueOf(foundCharacter));
|
|
||||||
}
|
|
||||||
|
|
||||||
foundCharacter = get(postfixFunctions, characterStartWithFinder);
|
|
||||||
if (foundCharacter != null) {
|
|
||||||
return new Result(postfix_function, String.valueOf(foundCharacter));
|
|
||||||
}
|
|
||||||
|
|
||||||
foundCharacter = get(unaryOperations, characterStartWithFinder);
|
|
||||||
if (foundCharacter != null) {
|
|
||||||
return new Result(unary_operation, String.valueOf(foundCharacter));
|
|
||||||
}
|
|
||||||
|
|
||||||
foundCharacter = get(binaryOperations, characterStartWithFinder);
|
|
||||||
if (foundCharacter != null) {
|
|
||||||
return new Result(binary_operation, String.valueOf(foundCharacter));
|
|
||||||
}
|
|
||||||
|
|
||||||
foundString = get(groupSymbols, stringStartWithFinder);
|
|
||||||
if (foundString != null) {
|
|
||||||
return new Result(MathType.group_symbols, foundString);
|
|
||||||
}
|
|
||||||
|
|
||||||
foundCharacter = get(openGroupSymbols, characterStartWithFinder);
|
|
||||||
if (foundCharacter != null) {
|
|
||||||
return new Result(open_group_symbol, String.valueOf(foundCharacter));
|
|
||||||
}
|
|
||||||
|
|
||||||
foundCharacter = get(closeGroupSymbols, characterStartWithFinder);
|
|
||||||
if (foundCharacter != null) {
|
|
||||||
return new Result(close_group_symbol, String.valueOf(foundCharacter));
|
|
||||||
}
|
|
||||||
|
|
||||||
foundString = get(prefixFunctions, stringStartWithFinder);
|
|
||||||
if (foundString != null) {
|
|
||||||
return new Result(MathType.function, foundString);
|
|
||||||
}
|
|
||||||
|
|
||||||
foundString = get(CalculatorEngine.instance.getVarsRegister().getVarNames(), stringStartWithFinder);
|
|
||||||
if (foundString != null) {
|
|
||||||
return new Result(MathType.constant, foundString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Result(MathType.text, text.substring(i));
|
return new Result(MathType.text, text.substring(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static List<MathType> mathTypesByPriority;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static List<MathType> getMathTypesByPriority() {
|
||||||
|
if ( mathTypesByPriority == null ) {
|
||||||
|
final List<MathType> result = CollectionsUtils.asList(MathType.values());
|
||||||
|
|
||||||
|
Collections.sort(result, new Comparator<MathType>() {
|
||||||
|
@Override
|
||||||
|
public int compare(MathType l, MathType r) {
|
||||||
|
return l.priority.compareTo(r.priority);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mathTypesByPriority = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mathTypesByPriority;
|
||||||
|
}
|
||||||
|
|
||||||
public static class Result {
|
public static class Result {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@ -149,7 +180,7 @@ public enum MathType {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private final String match;
|
private final String match;
|
||||||
|
|
||||||
public Result(@NotNull MathType mathType, @NotNull String match){
|
public Result(@NotNull MathType mathType, @NotNull String match) {
|
||||||
this.mathType = mathType;
|
this.mathType = mathType;
|
||||||
|
|
||||||
this.match = match;
|
this.match = match;
|
||||||
|
@ -39,7 +39,7 @@ public enum CalculatorEngine {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
|
|
||||||
private int numberOfFractionDigits = 5;
|
private int precision = 5;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public final TextProcessor<PreparedExpression> preprocessor = new ToJsclTextProcessor();
|
public final TextProcessor<PreparedExpression> preprocessor = new ToJsclTextProcessor();
|
||||||
@ -85,12 +85,12 @@ public enum CalculatorEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNumberOfFractionDigits() {
|
public int getPrecision() {
|
||||||
return numberOfFractionDigits;
|
return precision;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNumberOfFractionDigits(int numberOfFractionDigits) {
|
public void setPrecision(int precision) {
|
||||||
this.numberOfFractionDigits = numberOfFractionDigits;
|
this.precision = precision;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(@Nullable Context context, @Nullable SharedPreferences preferences) throws EvalError {
|
public void init(@Nullable Context context, @Nullable SharedPreferences preferences) throws EvalError {
|
||||||
@ -105,7 +105,7 @@ public enum CalculatorEngine {
|
|||||||
if (preferences != null) {
|
if (preferences != null) {
|
||||||
final NumberMapper<Integer> integerNumberMapper = new NumberMapper<Integer>(Integer.class);
|
final NumberMapper<Integer> integerNumberMapper = new NumberMapper<Integer>(Integer.class);
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
this.setNumberOfFractionDigits(integerNumberMapper.parseValue(preferences.getString(RESULT_PRECISION_P_KEY, RESULT_PRECISION_DEFAULT)));
|
this.setPrecision(integerNumberMapper.parseValue(preferences.getString(RESULT_PRECISION_P_KEY, RESULT_PRECISION_DEFAULT)));
|
||||||
}
|
}
|
||||||
|
|
||||||
varsRegister.init(context, preferences);
|
varsRegister.init(context, preferences);
|
||||||
|
@ -50,7 +50,7 @@ class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
|
|||||||
|
|
||||||
// NOTE: fix for jscl for EMPTY functions processing (see tests)
|
// NOTE: fix for jscl for EMPTY functions processing (see tests)
|
||||||
startsWithFinder.setI(i + 1);
|
startsWithFinder.setI(i + 1);
|
||||||
if ( i < s.length() && CollectionsUtils.get(MathType.groupSymbols, startsWithFinder) != null) {
|
if ( i < s.length() && CollectionsUtils.get(MathType.openGroupSymbols, startsWithFinder) != null) {
|
||||||
throw new ParseException("Empty function: " + mathTypeResult.getMatch());
|
throw new ParseException("Empty function: " + mathTypeResult.getMatch());
|
||||||
/*i += 2;
|
/*i += 2;
|
||||||
sb.append("(" + SPECIAL_STRING + ")");
|
sb.append("(" + SPECIAL_STRING + ")");
|
||||||
@ -78,7 +78,7 @@ class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
|
|||||||
startsWithFinder.setI(i);
|
startsWithFinder.setI(i);
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
String functionName = CollectionsUtils.get(MathType.prefixFunctions, startsWithFinder);
|
String functionName = CollectionsUtils.get(MathType.function.getTokens(), startsWithFinder);
|
||||||
if (functionName == null) {
|
if (functionName == null) {
|
||||||
String varName = CollectionsUtils.get(CalculatorEngine.instance.getVarsRegister().getVarNames(), startsWithFinder);
|
String varName = CollectionsUtils.get(CalculatorEngine.instance.getVarsRegister().getVarNames(), startsWithFinder);
|
||||||
if (varName != null) {
|
if (varName != null) {
|
||||||
@ -114,7 +114,7 @@ class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
|
|||||||
for (Var var : CalculatorEngine.instance.getVarsRegister().getVars()) {
|
for (Var var : CalculatorEngine.instance.getVarsRegister().getVars()) {
|
||||||
if (!var.isSystem()) {
|
if (!var.isSystem()) {
|
||||||
if (s.startsWith(var.getName(), i)) {
|
if (s.startsWith(var.getName(), i)) {
|
||||||
if (CollectionsUtils.get(MathType.prefixFunctions, startsWithFinder) == null) {
|
if (CollectionsUtils.get(MathType.function.getTokens(), startsWithFinder) == null) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,7 +149,7 @@ class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
|
|||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
final EndsWithFinder endsWithFinder = new EndsWithFinder(s);
|
final EndsWithFinder endsWithFinder = new EndsWithFinder(s);
|
||||||
endsWithFinder.setI(i + 1);
|
endsWithFinder.setI(i + 1);
|
||||||
if (!CollectionsUtils.contains(MathType.prefixFunctions, FilterType.included, endsWithFinder)) {
|
if (!CollectionsUtils.contains(MathType.function.getTokens(), FilterType.included, endsWithFinder)) {
|
||||||
MathType type = MathType.getType(s, i).getMathType();
|
MathType type = MathType.getType(s, i).getMathType();
|
||||||
if (type != MathType.constant) {
|
if (type != MathType.constant) {
|
||||||
return true;
|
return true;
|
||||||
@ -204,36 +204,16 @@ class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
|
|||||||
@NotNull String s,
|
@NotNull String s,
|
||||||
int i,
|
int i,
|
||||||
@Nullable MathType.Result mathTypeBeforeResult) {
|
@Nullable MathType.Result mathTypeBeforeResult) {
|
||||||
MathType.Result result = MathType.getType(s, i);
|
final MathType.Result result = MathType.getType(s, i);
|
||||||
|
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
|
|
||||||
final MathType mathType = result.getMathType();
|
final MathType current = result.getMathType();
|
||||||
assert mathTypeBeforeResult != null;
|
assert mathTypeBeforeResult != null;
|
||||||
final MathType mathTypeBefore = mathTypeBeforeResult.getMathType();
|
final MathType before = mathTypeBeforeResult.getMathType();
|
||||||
|
|
||||||
if (mathTypeBefore == MathType.constant || (mathTypeBefore != MathType.binary_operation &&
|
if (current.isNeedMultiplicationSignBefore(before)) {
|
||||||
mathTypeBefore != MathType.unary_operation &&
|
|
||||||
mathTypeBefore != MathType.power_10 &&
|
|
||||||
mathTypeBefore != MathType.function &&
|
|
||||||
mathTypeBefore != MathType.open_group_symbol)) {
|
|
||||||
|
|
||||||
if (mathType == MathType.constant) {
|
|
||||||
sb.append("*");
|
sb.append("*");
|
||||||
} else if (mathType == MathType.power_10) {
|
|
||||||
sb.append("*");
|
|
||||||
} else if (mathType == MathType.open_group_symbol && mathTypeBefore != null) {
|
|
||||||
sb.append("*");
|
|
||||||
} else if (mathType == MathType.digit && ((mathTypeBefore != MathType.digit && mathTypeBefore != MathType.dot) || mathTypeBefore == MathType.constant)) {
|
|
||||||
sb.append("*");
|
|
||||||
} else {
|
|
||||||
for (String function : MathType.prefixFunctions) {
|
|
||||||
if (s.startsWith(function, i)) {
|
|
||||||
sb.append("*");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ import bsh.EvalError;
|
|||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.simpleframework.xml.Attribute;
|
|
||||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
import org.solovyev.android.calculator.jscl.JsclOperation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,27 +27,52 @@ public class CalculatorEngineTest {
|
|||||||
public void testEvaluate() throws Exception {
|
public void testEvaluate() throws Exception {
|
||||||
final CalculatorEngine cm = CalculatorEngine.instance;
|
final CalculatorEngine cm = CalculatorEngine.instance;
|
||||||
|
|
||||||
Assert.assertEquals("4.0", cm.evaluate(JsclOperation.numeric, "2+2"));
|
Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "2+2"));
|
||||||
Assert.assertEquals("-0.7568", cm.evaluate(JsclOperation.numeric, "sin(4)"));
|
Assert.assertEquals("-0.757", cm.evaluate(JsclOperation.numeric, "sin(4)"));
|
||||||
Assert.assertEquals("0.5236", cm.evaluate(JsclOperation.numeric, "asin(0.5)"));
|
Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "asin(0.5)"));
|
||||||
Assert.assertEquals("-0.39626", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)"));
|
Assert.assertEquals("-0.396", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)"));
|
||||||
Assert.assertEquals("-0.5604", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)sqrt(2)"));
|
Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)sqrt(2)"));
|
||||||
Assert.assertEquals("-0.5604", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)"));
|
Assert.assertEquals("-0.56", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)"));
|
||||||
Assert.assertEquals("7.38906", cm.evaluate(JsclOperation.numeric, "e^2"));
|
Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "e^2"));
|
||||||
Assert.assertEquals("7.38906", cm.evaluate(JsclOperation.numeric, "exp(1)^2"));
|
Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(1)^2"));
|
||||||
Assert.assertEquals("7.38906", cm.evaluate(JsclOperation.numeric, "exp(2)"));
|
Assert.assertEquals("7.389", cm.evaluate(JsclOperation.numeric, "exp(2)"));
|
||||||
Assert.assertEquals("2.0+i", cm.evaluate(JsclOperation.numeric, "2*1+sqrt(-1)"));
|
Assert.assertEquals("2+i", cm.evaluate(JsclOperation.numeric, "2*1+sqrt(-1)"));
|
||||||
Assert.assertEquals("0.92054+3.14159i", cm.evaluate(JsclOperation.numeric, "ln(5cosh(38π√(2cos(2))))"));
|
Assert.assertEquals("0.921+3.142i", cm.evaluate(JsclOperation.numeric, "ln(5cosh(38π√(2cos(2))))"));
|
||||||
Assert.assertEquals("7.38906i", cm.evaluate(JsclOperation.numeric, "iexp(2)"));
|
Assert.assertEquals("7.389i", cm.evaluate(JsclOperation.numeric, "iexp(2)"));
|
||||||
Assert.assertEquals("2.0+7.38906i", cm.evaluate(JsclOperation.numeric, "2+iexp(2)"));
|
Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+iexp(2)"));
|
||||||
Assert.assertEquals("2.0+7.38906i", cm.evaluate(JsclOperation.numeric, "2+√(-1)exp(2)"));
|
Assert.assertEquals("2+7.389i", cm.evaluate(JsclOperation.numeric, "2+√(-1)exp(2)"));
|
||||||
Assert.assertEquals("2.0-2.5i", cm.evaluate(JsclOperation.numeric, "2-2.5i"));
|
Assert.assertEquals("2-2.5i", cm.evaluate(JsclOperation.numeric, "2-2.5i"));
|
||||||
Assert.assertEquals("-2.0-2.5i", cm.evaluate(JsclOperation.numeric, "-2-2.5i"));
|
Assert.assertEquals("-2-2.5i", cm.evaluate(JsclOperation.numeric, "-2-2.5i"));
|
||||||
Assert.assertEquals("-2.0+2.5i", cm.evaluate(JsclOperation.numeric, "-2+2.5i"));
|
Assert.assertEquals("-2+2.5i", cm.evaluate(JsclOperation.numeric, "-2+2.5i"));
|
||||||
Assert.assertEquals("-2.0+2.1i", cm.evaluate(JsclOperation.numeric, "-2+2.1i"));
|
Assert.assertEquals("-2+2.1i", cm.evaluate(JsclOperation.numeric, "-2+2.1i"));
|
||||||
Assert.assertEquals("-3.41007+3.41007i", cm.evaluate(JsclOperation.numeric, "(5tan(2i)+2i)/(1-i)"));
|
Assert.assertEquals("-3.41+3.41i", cm.evaluate(JsclOperation.numeric, "(5tan(2i)+2i)/(1-i)"));
|
||||||
Assert.assertEquals("-0.1-0.2i", cm.evaluate(JsclOperation.numeric, "(1-i)/(2+6i)"));
|
Assert.assertEquals("-0.1-0.2i", cm.evaluate(JsclOperation.numeric, "(1-i)/(2+6i)"));
|
||||||
|
|
||||||
|
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("si", 5d));
|
||||||
|
|
||||||
|
Assert.assertEquals("-0.959", cm.evaluate(JsclOperation.numeric, "sin(5)"));
|
||||||
|
Assert.assertEquals("-4.795", cm.evaluate(JsclOperation.numeric, "sin(5)si"));
|
||||||
|
Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "sisin(5)si"));
|
||||||
|
Assert.assertEquals("-23.973", cm.evaluate(JsclOperation.numeric, "si*sin(5)si"));
|
||||||
|
Assert.assertEquals("-3.309", cm.evaluate(JsclOperation.numeric, "sisin(5si)si"));
|
||||||
|
|
||||||
|
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("s", 1d));
|
||||||
|
Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si"));
|
||||||
|
|
||||||
|
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("k", 3.5d));
|
||||||
|
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("k1", 4d));
|
||||||
|
Assert.assertEquals("4", cm.evaluate(JsclOperation.numeric, "k11"));
|
||||||
|
|
||||||
|
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("t", (String)null));
|
||||||
|
Assert.assertEquals("11×t", cm.evaluate(JsclOperation.numeric, "t11"));
|
||||||
|
Assert.assertEquals("11×e×t", cm.evaluate(JsclOperation.numeric, "t11e"));
|
||||||
|
Assert.assertEquals("11×Infinity×t", cm.evaluate(JsclOperation.numeric, "t11∞"));
|
||||||
|
Assert.assertEquals("-t+t^3", cm.evaluate(JsclOperation.numeric, "t(t-1)(t+1)"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEmptyFunction() throws Exception {
|
||||||
|
final CalculatorEngine cm = CalculatorEngine.instance;
|
||||||
try {
|
try {
|
||||||
cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos(cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos())))))))))))))))))))))))))))))))))))))");
|
cm.evaluate(JsclOperation.numeric, "cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos(cos(cos(cos(cos(acos(acos(acos(acos(acos(acos(acos(acos(cos(cos(cos(cos(cosh(acos(cos())))))))))))))))))))))))))))))))))))))");
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
@ -60,78 +84,28 @@ public class CalculatorEngineTest {
|
|||||||
Assert.fail();
|
Assert.fail();
|
||||||
} catch (ParseException e){
|
} catch (ParseException e){
|
||||||
}
|
}
|
||||||
Assert.assertEquals("0.73909", 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))))))))))))))))))))))))))))))))))))"));
|
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))))))))))))))))))))))))))))))))))))"));
|
||||||
|
|
||||||
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("si", 5d));
|
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("si", 5d));
|
||||||
Assert.assertEquals("5.0", cm.evaluate(JsclOperation.numeric, "si"));
|
Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si"));
|
||||||
try {
|
try {
|
||||||
cm.evaluate(JsclOperation.numeric, "sin");
|
cm.evaluate(JsclOperation.numeric, "sin");
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
} catch (EvalError e) {
|
} catch (EvalError e) {
|
||||||
}
|
}
|
||||||
Assert.assertEquals("-0.95892", cm.evaluate(JsclOperation.numeric, "sin(5)"));
|
|
||||||
Assert.assertEquals("-4.79462", cm.evaluate(JsclOperation.numeric, "sin(5)si"));
|
|
||||||
Assert.assertEquals("-23.97311", cm.evaluate(JsclOperation.numeric, "sisin(5)si"));
|
|
||||||
Assert.assertEquals("-23.97311", cm.evaluate(JsclOperation.numeric, "si*sin(5)si"));
|
|
||||||
Assert.assertEquals("-3.30879", cm.evaluate(JsclOperation.numeric, "sisin(5si)si"));
|
|
||||||
|
|
||||||
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("s", 1d));
|
|
||||||
Assert.assertEquals("5.0", cm.evaluate(JsclOperation.numeric, "si"));
|
|
||||||
|
|
||||||
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("k", 3.5d));
|
|
||||||
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("k1", 4d));
|
|
||||||
Assert.assertEquals("4.0", cm.evaluate(JsclOperation.numeric, "k11"));
|
|
||||||
|
|
||||||
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("t", (String)null));
|
|
||||||
Assert.assertEquals("11*t", cm.evaluate(JsclOperation.numeric, "t11"));
|
|
||||||
Assert.assertEquals("11*2.718281828459045*t", cm.evaluate(JsclOperation.numeric, "t11e"));
|
|
||||||
Assert.assertEquals("11*Infinity*t", cm.evaluate(JsclOperation.numeric, "t11∞"));
|
|
||||||
Assert.assertEquals("-t+t^3", cm.evaluate(JsclOperation.numeric, "t(t-1)(t+1)"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface TestInterface {
|
@Test
|
||||||
Integer getField();
|
public void testRounding() throws Exception {
|
||||||
}
|
final CalculatorEngine cm = CalculatorEngine.instance;
|
||||||
|
|
||||||
public class TestClass implements TestInterface{
|
cm.setPrecision(2);
|
||||||
|
Assert.assertEquals("12345678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7"));
|
||||||
|
cm.setPrecision(10);
|
||||||
|
Assert.assertEquals("12345678.9", cm.evaluate(JsclOperation.numeric, "1.23456789E7"));
|
||||||
|
Assert.assertEquals("123456789", cm.evaluate(JsclOperation.numeric, "1.234567890E8"));
|
||||||
|
Assert.assertEquals("1234567890.1", cm.evaluate(JsclOperation.numeric, "1.2345678901E9"));
|
||||||
|
|
||||||
@Attribute(required = true)
|
|
||||||
private Integer field;
|
|
||||||
|
|
||||||
public TestClass() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public TestClass(Integer field) {
|
|
||||||
this.field = field;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getField() {
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setField(Integer field) {
|
|
||||||
this.field = field;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class NewTestClass implements TestInterface{
|
|
||||||
|
|
||||||
@Attribute
|
|
||||||
private Integer field;
|
|
||||||
|
|
||||||
public NewTestClass() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public NewTestClass(Integer field) {
|
|
||||||
this.field = field;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getField() {
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setField(Integer field) {
|
|
||||||
this.field = field;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ package org.solovyev.android.calculator.model;
|
|||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.solovyev.android.calculator.jscl.JsclOperation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: serso
|
* User: serso
|
||||||
@ -27,6 +26,17 @@ public class ToJsclTextProcessorTest {
|
|||||||
public void testProcess() throws Exception {
|
public void testProcess() throws Exception {
|
||||||
final ToJsclTextProcessor preprocessor = new ToJsclTextProcessor();
|
final ToJsclTextProcessor preprocessor = new ToJsclTextProcessor();
|
||||||
|
|
||||||
|
Assert.assertEquals( "", preprocessor.process("").toString());
|
||||||
|
Assert.assertEquals( "()", preprocessor.process("[]").toString());
|
||||||
|
Assert.assertEquals( "()*()", preprocessor.process("[][]").toString());
|
||||||
|
Assert.assertEquals( "()*(1)", preprocessor.process("[][1]").toString());
|
||||||
|
Assert.assertEquals( "(0)*(1)", preprocessor.process("[0][1]").toString());
|
||||||
|
Assert.assertEquals( "(0)*(1*10^)", preprocessor.process("[0][1E]").toString());
|
||||||
|
Assert.assertEquals( "(0)*(1*10^1)", preprocessor.process("[0][1E1]").toString());
|
||||||
|
Assert.assertEquals( "(0)*(1*10^-1)", preprocessor.process("[0][1E-1]").toString());
|
||||||
|
Assert.assertEquals( "(0)*(1.*10^-1)", preprocessor.process("[0][1.E-1]").toString());
|
||||||
|
Assert.assertEquals( "(0)*(2*10^-1)", preprocessor.process("[0][2*E-1]").toString());
|
||||||
|
Assert.assertEquals( "(0)*log(1)*(2*10^-1)", preprocessor.process("[0]ln(1)[2*E-1]").toString());
|
||||||
Assert.assertEquals( "sin(4)*asin(0.5)*sqrt(2)", preprocessor.process("sin(4)asin(0.5)sqrt(2)").toString());
|
Assert.assertEquals( "sin(4)*asin(0.5)*sqrt(2)", preprocessor.process("sin(4)asin(0.5)sqrt(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( "3.141592653589793*sin(4)*3.141592653589793*cos(sqrt(5))", preprocessor.process("πsin(4)πcos(√(5))").toString());
|
Assert.assertEquals( "3.141592653589793*sin(4)*3.141592653589793*cos(sqrt(5))", preprocessor.process("πsin(4)πcos(√(5))").toString());
|
||||||
|
Loading…
Reference in New Issue
Block a user