New architecture

This commit is contained in:
Sergey Solovyev 2012-09-23 18:25:15 +04:00
parent 233c685a49
commit f03c2496a6
27 changed files with 1002 additions and 759 deletions

View File

@ -1,85 +1,84 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.calculator;
import jscl.MathEngine;
import jscl.NumeralBase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.common.text.StringUtils;
/**
* User: serso
* Date: 12/15/11
* Time: 9:01 PM
*/
public abstract class AbstractNumberBuilder {
@NotNull
protected final MathEngine engine;
@Nullable
protected StringBuilder numberBuilder = null;
@Nullable
protected NumeralBase nb;
protected AbstractNumberBuilder(@NotNull MathEngine engine) {
this.engine = engine;
this.nb = engine.getNumeralBase();
}
/**
* 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
*/
protected boolean canContinue(@NotNull MathType.Result mathTypeResult) {
boolean result = mathTypeResult.getMathType().getGroupType() == MathType.MathGroupType.number &&
!spaceBefore(mathTypeResult) &&
numeralBaseCheck(mathTypeResult) &&
numeralBaseInTheStart(mathTypeResult.getMathType()) || isSignAfterE(mathTypeResult);
return result;
}
private boolean spaceBefore(@NotNull MathType.Result mathTypeResult) {
return numberBuilder == null && StringUtils.isEmpty(mathTypeResult.getMatch().trim());
}
private boolean numeralBaseInTheStart(@NotNull MathType mathType) {
return mathType != MathType.numeral_base || numberBuilder == null;
}
private boolean numeralBaseCheck(@NotNull MathType.Result mathType) {
return mathType.getMathType() != MathType.digit || getNumeralBase().getAcceptableCharacters().contains(mathType.getMatch().charAt(0));
}
private boolean isSignAfterE(@NotNull MathType.Result mathTypeResult) {
if (!isHexMode()) {
if ("-".equals(mathTypeResult.getMatch()) || "+".equals(mathTypeResult.getMatch())) {
final StringBuilder localNb = numberBuilder;
if (localNb != null && localNb.length() > 0) {
if (localNb.charAt(localNb.length() - 1) == MathType.POWER_10) {
return true;
}
}
}
}
return false;
}
public boolean isHexMode() {
return nb == NumeralBase.hex || (nb == null && engine.getNumeralBase() == NumeralBase.hex);
}
@NotNull
protected NumeralBase getNumeralBase() {
return nb == null ? engine.getNumeralBase() : nb;
}
}
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.calculator;
import jscl.NumeralBase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.common.text.StringUtils;
/**
* User: serso
* Date: 12/15/11
* Time: 9:01 PM
*/
public abstract class AbstractNumberBuilder {
@NotNull
protected final CalculatorEngine engine;
@Nullable
protected StringBuilder numberBuilder = null;
@Nullable
protected NumeralBase nb;
protected AbstractNumberBuilder(@NotNull CalculatorEngine engine) {
this.engine = engine;
this.nb = engine.getNumeralBase();
}
/**
* 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
*/
protected boolean canContinue(@NotNull MathType.Result mathTypeResult) {
boolean result = mathTypeResult.getMathType().getGroupType() == MathType.MathGroupType.number &&
!spaceBefore(mathTypeResult) &&
numeralBaseCheck(mathTypeResult) &&
numeralBaseInTheStart(mathTypeResult.getMathType()) || isSignAfterE(mathTypeResult);
return result;
}
private boolean spaceBefore(@NotNull MathType.Result mathTypeResult) {
return numberBuilder == null && StringUtils.isEmpty(mathTypeResult.getMatch().trim());
}
private boolean numeralBaseInTheStart(@NotNull MathType mathType) {
return mathType != MathType.numeral_base || numberBuilder == null;
}
private boolean numeralBaseCheck(@NotNull MathType.Result mathType) {
return mathType.getMathType() != MathType.digit || getNumeralBase().getAcceptableCharacters().contains(mathType.getMatch().charAt(0));
}
private boolean isSignAfterE(@NotNull MathType.Result mathTypeResult) {
if (!isHexMode()) {
if ("-".equals(mathTypeResult.getMatch()) || "+".equals(mathTypeResult.getMatch())) {
final StringBuilder localNb = numberBuilder;
if (localNb != null && localNb.length() > 0) {
if (localNb.charAt(localNb.length() - 1) == MathType.POWER_10) {
return true;
}
}
}
}
return false;
}
public boolean isHexMode() {
return nb == NumeralBase.hex || (nb == null && engine.getNumeralBase() == NumeralBase.hex);
}
@NotNull
protected NumeralBase getNumeralBase() {
return nb == null ? engine.getNumeralBase() : nb;
}
}

View File

@ -15,6 +15,16 @@ import org.solovyev.common.history.HistoryControl;
*/
public interface Calculator extends CalculatorEventContainer, HistoryControl<CalculatorHistoryState> {
void init();
/*
**********************************************************************
*
* CALCULATIONS
*
**********************************************************************
*/
void evaluate();
void simplify();
@ -31,11 +41,16 @@ public interface Calculator extends CalculatorEventContainer, HistoryControl<Cal
@NotNull
CalculatorEventDataId convert(@NotNull Generic generic, @NotNull NumeralBase to);
/*
**********************************************************************
*
* EVENTS
*
**********************************************************************
*/
@NotNull
CalculatorEventDataId fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data);
@NotNull
CalculatorEventDataId fireCalculatorEvent(@NotNull CalculatorEventType calculatorEventType, @Nullable Object data, @NotNull Long sequenceId);
void init();
}

View File

@ -1,11 +1,15 @@
package org.solovyev.android.calculator;
import jscl.AngleUnit;
import jscl.MathEngine;
import jscl.NumeralBase;
import jscl.math.function.Function;
import jscl.math.function.IConstant;
import jscl.math.operator.Operator;
import org.jetbrains.annotations.NotNull;
import java.text.DecimalFormatSymbols;
/**
* User: Solovyev_S
* Date: 20.09.12
@ -13,8 +17,27 @@ import org.jetbrains.annotations.NotNull;
*/
public interface CalculatorEngine {
@NotNull
String getMultiplicationSign();
/*
**********************************************************************
*
* INIT
*
**********************************************************************
*/
void init();
void reset();
void softReset();
/*
**********************************************************************
*
* REGISTRIES
*
**********************************************************************
*/
@NotNull
CalculatorMathRegistry<IConstant> getVarsRegistry();
@ -29,11 +52,46 @@ public interface CalculatorEngine {
CalculatorMathRegistry<Operator> getPostfixFunctionsRegistry();
@NotNull
MathEngine getEngine();
CalculatorMathEngine getMathEngine();
void init();
@Deprecated
@NotNull
MathEngine getMathEngine0();
void reset();
/*
**********************************************************************
*
* PREFERENCES
*
**********************************************************************
*/
void softReset();
@NotNull
String getMultiplicationSign();
void setUseGroupingSeparator(boolean useGroupingSeparator);
void setGroupingSeparator(char groupingSeparator);
void setPrecision(@NotNull Integer precision);
void setRoundResult(@NotNull Boolean round);
@NotNull
AngleUnit getAngleUnits();
void setAngleUnits(@NotNull AngleUnit angleUnits);
@NotNull
NumeralBase getNumeralBase();
void setNumeralBase(@NotNull NumeralBase numeralBase);
void setMultiplicationSign(@NotNull String multiplicationSign);
void setScienceNotation(@NotNull Boolean scienceNotation);
void setTimeout(@NotNull Integer timeout);
void setDecimalGroupSymbols(@NotNull DecimalFormatSymbols decimalGroupSymbols);
}

View File

@ -0,0 +1,320 @@
package org.solovyev.android.calculator;
import jscl.AngleUnit;
import jscl.JsclMathEngine;
import jscl.MathEngine;
import jscl.NumeralBase;
import jscl.math.Generic;
import jscl.math.function.Function;
import jscl.math.function.IConstant;
import jscl.math.operator.Operator;
import jscl.text.ParseException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.text.DecimalFormatSymbols;
/**
* User: serso
* Date: 9/23/12
* Time: 5:34 PM
*/
public class CalculatorEngineImpl implements CalculatorEngine {
/*
**********************************************************************
*
* CONSTANTS
*
**********************************************************************
*/
private static final String MULTIPLICATION_SIGN_DEFAULT = "×";
private static final String MAX_CALCULATION_TIME_DEFAULT = "5";
/*
**********************************************************************
*
* ENGINE/REGISTRIES
*
**********************************************************************
*/
@NotNull
private final MathEngine engine;
@NotNull
private final CalculatorMathEngine mathEngine;
@NotNull
private final CalculatorMathRegistry<IConstant> varsRegistry;
@NotNull
private final CalculatorMathRegistry<Function> functionsRegistry;
@NotNull
private final CalculatorMathRegistry<Operator> operatorsRegistry;
@NotNull
private final CalculatorMathRegistry<Operator> postfixFunctionsRegistry;
@NotNull
private final Object lock;
/*
**********************************************************************
*
* PREFERENCES
*
**********************************************************************
*/
private int timeout = Integer.valueOf(MAX_CALCULATION_TIME_DEFAULT);
@NotNull
private String multiplicationSign = MULTIPLICATION_SIGN_DEFAULT;
public CalculatorEngineImpl(@NotNull JsclMathEngine engine,
@NotNull CalculatorMathRegistry<IConstant> varsRegistry,
@NotNull CalculatorMathRegistry<Function> functionsRegistry,
@NotNull CalculatorMathRegistry<Operator> operatorsRegistry,
@NotNull CalculatorMathRegistry<Operator> postfixFunctionsRegistry,
@Nullable Object lock) {
this.engine = engine;
this.mathEngine = new JsclCalculatorMathEngine(engine);
this.engine.setRoundResult(true);
this.engine.setUseGroupingSeparator(true);
this.varsRegistry = varsRegistry;
this.functionsRegistry = functionsRegistry;
this.operatorsRegistry = operatorsRegistry;
this.postfixFunctionsRegistry = postfixFunctionsRegistry;
this.lock = lock == null ? new Object() : lock;
}
/*
**********************************************************************
*
* REGISTRIES
*
**********************************************************************
*/
@NotNull
@Override
public CalculatorMathRegistry<IConstant> getVarsRegistry() {
return this.varsRegistry;
}
@NotNull
@Override
public CalculatorMathRegistry<Function> getFunctionsRegistry() {
return this.functionsRegistry;
}
@NotNull
@Override
public CalculatorMathRegistry<Operator> getOperatorsRegistry() {
return this.operatorsRegistry;
}
@NotNull
@Override
public CalculatorMathRegistry<Operator> getPostfixFunctionsRegistry() {
return this.postfixFunctionsRegistry;
}
@NotNull
@Override
public CalculatorMathEngine getMathEngine() {
return this.mathEngine;
}
@NotNull
@Override
public MathEngine getMathEngine0() {
return this.engine;
}
/*
**********************************************************************
*
* INIT
*
**********************************************************************
*/
@Override
public void init() {
synchronized (lock) {
reset();
}
}
@Override
public void reset() {
synchronized (lock) {
varsRegistry.load();
functionsRegistry.load();
operatorsRegistry.load();
postfixFunctionsRegistry.load();
}
}
@Override
public void softReset() {
// do nothing
}
/*
**********************************************************************
*
* PREFERENCES
*
**********************************************************************
*/
@NotNull
@Override
public String getMultiplicationSign() {
return this.multiplicationSign;
}
@Override
public void setUseGroupingSeparator(boolean useGroupingSeparator) {
synchronized (lock) {
this.engine.setUseGroupingSeparator(true);
}
}
@Override
public void setGroupingSeparator(char groupingSeparator) {
synchronized (lock) {
this.engine.setGroupingSeparator(groupingSeparator);
}
}
@Override
public void setPrecision(@NotNull Integer precision) {
synchronized (lock) {
this.engine.setPrecision(precision);
}
}
@Override
public void setRoundResult(@NotNull Boolean round) {
synchronized (lock) {
this.engine.setRoundResult(round);
}
}
@NotNull
@Override
public AngleUnit getAngleUnits() {
synchronized (lock) {
return this.engine.getAngleUnits();
}
}
@Override
public void setAngleUnits(@NotNull AngleUnit angleUnits) {
synchronized (lock) {
this.engine.setAngleUnits(angleUnits);
}
}
@NotNull
@Override
public NumeralBase getNumeralBase() {
synchronized (lock) {
return this.engine.getNumeralBase();
}
}
@Override
public void setNumeralBase(@NotNull NumeralBase numeralBase) {
synchronized (lock) {
this.engine.setNumeralBase(numeralBase);
}
}
@Override
public void setMultiplicationSign(@NotNull String multiplicationSign) {
this.multiplicationSign = multiplicationSign;
}
@Override
public void setScienceNotation(@NotNull Boolean scienceNotation) {
synchronized (lock) {
this.engine.setScienceNotation(scienceNotation);
}
}
@Override
public void setTimeout(@NotNull Integer timeout) {
this.timeout = timeout;
}
@Override
public void setDecimalGroupSymbols(@NotNull DecimalFormatSymbols decimalGroupSymbols) {
synchronized (lock) {
this.engine.setDecimalGroupSymbols(decimalGroupSymbols);
}
}
/*
**********************************************************************
*
* STATIC CLASSES
*
**********************************************************************
*/
private static final class JsclCalculatorMathEngine implements CalculatorMathEngine {
@NotNull
private final MathEngine mathEngine;
private JsclCalculatorMathEngine(@NotNull MathEngine mathEngine) {
this.mathEngine = mathEngine;
}
@NotNull
@Override
public String evaluate(@NotNull String expression) throws ParseException {
return this.mathEngine.evaluate(expression);
}
@NotNull
@Override
public String simplify(@NotNull String expression) throws ParseException {
return this.mathEngine.simplify(expression);
}
@NotNull
@Override
public String elementary(@NotNull String expression) throws ParseException {
return this.mathEngine.elementary(expression);
}
@NotNull
@Override
public Generic evaluateGeneric(@NotNull String expression) throws ParseException {
return this.mathEngine.evaluateGeneric(expression);
}
@NotNull
@Override
public Generic simplifyGeneric(@NotNull String expression) throws ParseException {
return this.mathEngine.simplifyGeneric(expression);
}
@NotNull
@Override
public Generic elementaryGeneric(@NotNull String expression) throws ParseException {
return this.mathEngine.elementaryGeneric(expression);
}
}
}

View File

@ -149,7 +149,7 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
fireCalculatorEvent(newConversionEventData(sequenceId), CalculatorEventType.conversion_started, null);
final NumeralBase from = CalculatorLocatorImpl.getInstance().getEngine().getEngine().getNumeralBase();
final NumeralBase from = CalculatorLocatorImpl.getInstance().getEngine().getNumeralBase();
if (from != to) {
String fromString = generic.toString();
@ -236,7 +236,7 @@ public class CalculatorImpl implements Calculator, CalculatorEventListener {
try {
final Generic result = operation.evaluateGeneric(jsclExpression);
final Generic result = operation.evaluateGeneric(jsclExpression, CalculatorLocatorImpl.getInstance().getEngine().getMathEngine());
// NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!)
result.toString();

View File

@ -0,0 +1,31 @@
package org.solovyev.android.calculator;
import jscl.math.Generic;
import jscl.text.ParseException;
import org.jetbrains.annotations.NotNull;
/**
* User: serso
* Date: 9/23/12
* Time: 6:05 PM
*/
public interface CalculatorMathEngine {
@NotNull
String evaluate(@NotNull String expression) throws ParseException;
@NotNull
String simplify(@NotNull String expression) throws ParseException;
@NotNull
String elementary(@NotNull String expression) throws ParseException;
@NotNull
Generic evaluateGeneric(@NotNull String expression) throws ParseException;
@NotNull
Generic simplifyGeneric(@NotNull String expression) throws ParseException;
@NotNull
Generic elementaryGeneric(@NotNull String expression) throws ParseException;
}

View File

@ -1,55 +1,54 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.calculator;
import jscl.MathEngine;
import jscl.NumeralBase;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.math.MathType;
/**
* User: serso
* Date: 12/15/11
* Time: 8:33 PM
*/
public class LiteNumberBuilder extends AbstractNumberBuilder {
public LiteNumberBuilder(@NotNull MathEngine engine) {
super(engine);
this.nb = engine.getNumeralBase();
}
public void process(@NotNull MathType.Result mathTypeResult) {
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());
}
} else {
// process current number (and go to the next one)
if (numberBuilder != null) {
numberBuilder = null;
// must set default numeral base (exit numeral base mode)
nb = engine.getNumeralBase();
}
}
}
}
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.calculator;
import jscl.NumeralBase;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.math.MathType;
/**
* User: serso
* Date: 12/15/11
* Time: 8:33 PM
*/
public class LiteNumberBuilder extends AbstractNumberBuilder {
public LiteNumberBuilder(@NotNull CalculatorEngine engine) {
super(engine);
this.nb = engine.getNumeralBase();
}
public void process(@NotNull MathType.Result mathTypeResult) {
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());
}
} else {
// process current number (and go to the next one)
if (numberBuilder != null) {
numberBuilder = null;
// must set default numeral base (exit numeral base mode)
nb = engine.getNumeralBase();
}
}
}
}

View File

@ -1,203 +1,202 @@
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.calculator;
import jscl.MathContext;
import jscl.MathEngine;
import jscl.NumeralBase;
import jscl.math.numeric.Real;
import jscl.text.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.AbstractNumberBuilder;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.common.MutableObject;
import java.util.ArrayList;
import java.util.List;
/**
* User: serso
* Date: 10/23/11
* Time: 2:57 PM
*/
public class NumberBuilder extends AbstractNumberBuilder {
public NumberBuilder(@NotNull MathEngine engine) {
super(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 text, @NotNull MathType.Result mathTypeResult, @Nullable MutableObject<Integer> offset) {
final MathType.Result possibleResult;
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 {
// process current number (and go to the next one)
possibleResult = processNumber(text, offset);
}
return possibleResult == null ? mathTypeResult : possibleResult;
}
/**
* 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 processNumber(@NotNull StringBuilder text, @Nullable MutableObject<Integer> offset) {
// total number of trimmed chars
int trimmedChars = 0;
String number = null;
// toXml numeral base (as later it might be replaced)
final NumeralBase localNb = getNumeralBase();
if (numberBuilder != null) {
try {
number = numberBuilder.toString();
// 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) {
final String trimmedNumber = number.replace(groupingSeparator, "");
trimmedChars += number.length() - trimmedNumber.length();
number = trimmedNumber;
}
// check if number still valid
toDouble(number, getNumeralBase(), engine);
} catch (NumberFormatException e) {
// number is not valid => stop
number = null;
}
numberBuilder = null;
// must set default numeral base (exit numeral base mode)
nb = engine.getNumeralBase();
}
return replaceNumberInText(text, number, trimmedChars, offset, localNb, engine);
}
@Nullable
private static MathType.Result replaceNumberInText(@NotNull StringBuilder text,
@Nullable String number,
int trimmedChars,
@Nullable MutableObject<Integer> offset,
@NotNull NumeralBase nb,
@NotNull final MathEngine engine) {
MathType.Result result = null;
if (number != null) {
// in any case remove old number from text
final int oldNumberLength = number.length() + trimmedChars;
text.delete(text.length() - oldNumberLength, text.length());
final String newNumber = formatNumber(number, nb, engine);
if (offset != null) {
// register offset between old number and new number
offset.setObject(newNumber.length() - oldNumberLength);
}
text.append(newNumber);
}
return result;
}
@NotNull
private static String formatNumber(@NotNull String number, @NotNull NumeralBase nb, @NotNull MathEngine engine) {
String result;
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 = engine.addGroupingSeparators(nb, number);
} else {
final String partBeforeE;
if (indexOfE != 0) {
partBeforeE = engine.addGroupingSeparators(nb, number.substring(0, indexOfE));
} else {
partBeforeE = "";
}
result = partBeforeE + number.substring(indexOfE);
}
} else {
final String integerPart;
if (indexOfDot != 0) {
integerPart = engine.addGroupingSeparators(nb, number.substring(0, indexOfDot));
} else {
integerPart = "";
}
result = integerPart + number.substring(indexOfDot);
}
return result;
}
@NotNull
private static Double toDouble(@NotNull String s, @NotNull NumeralBase nb, @NotNull final MathContext mc) throws NumberFormatException {
final NumeralBase defaultNb = mc.getNumeralBase();
try {
mc.setNumeralBase(nb);
try {
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), mc), null).content()).doubleValue();
} catch (ParseException e1) {
throw new NumberFormatException();
}
}
} finally {
mc.setNumeralBase(defaultNb);
}
}
}
/*
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
* For more information, please, contact se.solovyev@gmail.com
* or visit http://se.solovyev.org
*/
package org.solovyev.android.calculator;
import jscl.MathContext;
import jscl.MathEngine;
import jscl.NumeralBase;
import jscl.math.numeric.Real;
import jscl.text.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.common.MutableObject;
import java.util.ArrayList;
import java.util.List;
/**
* User: serso
* Date: 10/23/11
* Time: 2:57 PM
*/
public class NumberBuilder extends AbstractNumberBuilder {
public NumberBuilder(@NotNull CalculatorEngine engine) {
super(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 text, @NotNull MathType.Result mathTypeResult, @Nullable MutableObject<Integer> offset) {
final MathType.Result possibleResult;
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 {
// process current number (and go to the next one)
possibleResult = processNumber(text, offset);
}
return possibleResult == null ? mathTypeResult : possibleResult;
}
/**
* 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 processNumber(@NotNull StringBuilder text, @Nullable MutableObject<Integer> offset) {
// total number of trimmed chars
int trimmedChars = 0;
String number = null;
// toXml numeral base (as later it might be replaced)
final NumeralBase localNb = getNumeralBase();
if (numberBuilder != null) {
try {
number = numberBuilder.toString();
// 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) {
final String trimmedNumber = number.replace(groupingSeparator, "");
trimmedChars += number.length() - trimmedNumber.length();
number = trimmedNumber;
}
// check if number still valid
toDouble(number, getNumeralBase(), engine.getMathEngine0());
} catch (NumberFormatException e) {
// number is not valid => stop
number = null;
}
numberBuilder = null;
// must set default numeral base (exit numeral base mode)
nb = engine.getNumeralBase();
}
return replaceNumberInText(text, number, trimmedChars, offset, localNb, engine.getMathEngine0());
}
@Nullable
private static MathType.Result replaceNumberInText(@NotNull StringBuilder text,
@Nullable String number,
int trimmedChars,
@Nullable MutableObject<Integer> offset,
@NotNull NumeralBase nb,
@NotNull final MathEngine engine) {
MathType.Result result = null;
if (number != null) {
// in any case remove old number from text
final int oldNumberLength = number.length() + trimmedChars;
text.delete(text.length() - oldNumberLength, text.length());
final String newNumber = formatNumber(number, nb, engine);
if (offset != null) {
// register offset between old number and new number
offset.setObject(newNumber.length() - oldNumberLength);
}
text.append(newNumber);
}
return result;
}
@NotNull
private static String formatNumber(@NotNull String number, @NotNull NumeralBase nb, @NotNull MathEngine engine) {
String result;
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 = engine.addGroupingSeparators(nb, number);
} else {
final String partBeforeE;
if (indexOfE != 0) {
partBeforeE = engine.addGroupingSeparators(nb, number.substring(0, indexOfE));
} else {
partBeforeE = "";
}
result = partBeforeE + number.substring(indexOfE);
}
} else {
final String integerPart;
if (indexOfDot != 0) {
integerPart = engine.addGroupingSeparators(nb, number.substring(0, indexOfDot));
} else {
integerPart = "";
}
result = integerPart + number.substring(indexOfDot);
}
return result;
}
@NotNull
private static Double toDouble(@NotNull String s, @NotNull NumeralBase nb, @NotNull final MathContext mc) throws NumberFormatException {
final NumeralBase defaultNb = mc.getNumeralBase();
try {
mc.setNumeralBase(nb);
try {
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), mc), null).content()).doubleValue();
} catch (ParseException e1) {
throw new NumberFormatException();
}
}
} finally {
mc.setNumeralBase(defaultNb);
}
}
}

View File

@ -52,7 +52,7 @@ public class ToJsclTextProcessor implements TextProcessor<PreparedExpression, St
MathType.Result mathTypeResult = null;
MathType.Result mathTypeBefore;
final LiteNumberBuilder nb = new LiteNumberBuilder(CalculatorLocatorImpl.getInstance().getEngine().getEngine());
final LiteNumberBuilder nb = new LiteNumberBuilder(CalculatorLocatorImpl.getInstance().getEngine());
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ' ') continue;
startsWithFinder.setI(i);

View File

@ -9,7 +9,7 @@ package org.solovyev.android.calculator.jscl;
import jscl.math.Generic;
import jscl.text.ParseException;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.CalculatorLocatorImpl;
import org.solovyev.android.calculator.CalculatorMathEngine;
import org.solovyev.android.calculator.text.DummyTextProcessor;
import org.solovyev.android.calculator.text.FromJsclSimplifyTextProcessor;
import org.solovyev.android.calculator.text.TextProcessor;
@ -39,28 +39,28 @@ public enum JsclOperation {
}
@NotNull
public final String evaluate(@NotNull String expression) throws ParseException {
public final String evaluate(@NotNull String expression, @NotNull CalculatorMathEngine engine) throws ParseException {
switch (this) {
case simplify:
return CalculatorLocatorImpl.getInstance().getEngine().getEngine().simplify(expression);
return engine.simplify(expression);
case elementary:
return CalculatorLocatorImpl.getInstance().getEngine().getEngine().elementary(expression);
return engine.elementary(expression);
case numeric:
return CalculatorLocatorImpl.getInstance().getEngine().getEngine().evaluate(expression);
return engine.evaluate(expression);
default:
throw new UnsupportedOperationException();
}
}
@NotNull
public final Generic evaluateGeneric(@NotNull String expression) throws ParseException {
public final Generic evaluateGeneric(@NotNull String expression, @NotNull CalculatorMathEngine engine) throws ParseException {
switch (this) {
case simplify:
return CalculatorLocatorImpl.getInstance().getEngine().getEngine().simplifyGeneric(expression);
return engine.simplifyGeneric(expression);
case elementary:
return CalculatorLocatorImpl.getInstance().getEngine().getEngine().elementaryGeneric(expression);
return engine.elementaryGeneric(expression);
case numeric:
return CalculatorLocatorImpl.getInstance().getEngine().getEngine().evaluateGeneric(expression);
return engine.evaluateGeneric(expression);
default:
throw new UnsupportedOperationException();
}

View File

@ -15,4 +15,4 @@
a:layout_width="fill_parent"
a:layout_height="fill_parent"
style="?controlButtonStyle"
a:onClick="numericButtonClickHandler"/>
a:onClick="equalsButtonClickHandler"/>

View File

@ -37,7 +37,7 @@ public class AndroidCalculator implements Calculator {
/*
**********************************************************************
*
* DELETED TO CALCULATOR
* DELEGATED TO CALCULATOR
*
**********************************************************************
*/

View File

@ -32,7 +32,7 @@ public class AndroidCalculatorDisplayView extends AutoResizeTextView implements
*/
@NotNull
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false, CalculatorLocatorImpl.getInstance().getEngine().getEngine());
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, false);
/*
**********************************************************************

View File

@ -31,7 +31,7 @@ public class AndroidCalculatorEditorView extends EditText implements SharedPrefe
private boolean highlightText = true;
@NotNull
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, true, CalculatorLocatorImpl.getInstance().getEngine().getEngine());
private final static TextProcessor<TextHighlighter.Result, String> textHighlighter = new TextHighlighter(Color.WHITE, true);
@NotNull
private volatile CalculatorEditorViewState viewState = CalculatorEditorViewStateImpl.newDefaultInstance();

View File

@ -531,7 +531,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
}
@SuppressWarnings({"UnusedDeclaration"})
public void numericButtonClickHandler(@NotNull View v) {
public void equalsButtonClickHandler(@NotNull View v) {
getCalculator().evaluate();
}
@ -655,8 +655,6 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
if (!theme.equals(newTheme) || !layout.equals(newLayout)) {
AndroidUtils.restartActivity(this);
}
getCalculator().evaluate();
}
@Override
@ -674,13 +672,6 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
dpclRegister.announce().onDragPreferencesChange(SimpleOnDragListener.getPreferences(preferences, this));
}
if (AndroidCalculatorEngine.Preferences.getPreferenceKeys().contains(key)) {
CalculatorLocatorImpl.getInstance().getEngine().softReset();
// reevaluate in order to update values (in case of preferences changed from the main window, like numeral bases and angle units)
this.getCalculator().evaluate();
}
if ( CalculatorPreferences.Gui.usePrevAsBack.getKey().equals(key) ) {
useBackAsPrev = CalculatorPreferences.Gui.usePrevAsBack.getPreference(preferences);
}

View File

@ -42,7 +42,7 @@ enum ConversionMenuItem implements AMenuItem<CalculatorDisplayViewState> {
@Override
public void onClick(@NotNull CalculatorDisplayViewState data, @NotNull Context context) {
final NumeralBase fromNumeralBase = CalculatorLocatorImpl.getInstance().getEngine().getEngine().getNumeralBase();
final NumeralBase fromNumeralBase = CalculatorLocatorImpl.getInstance().getEngine().getNumeralBase();
final Generic lastResult = data.getResult();

View File

@ -160,7 +160,7 @@ public class FunctionEditorSaver implements DialogInterface.OnClickListener{
if (!StringUtils.isEmpty(name)) {
try {
assert name != null;
Identifier.parser.parse(Parser.Parameters.newInstance(name, new MutableInt(0), CalculatorLocatorImpl.getInstance().getEngine().getEngine()), null);
Identifier.parser.parse(Parser.Parameters.newInstance(name, new MutableInt(0), CalculatorLocatorImpl.getInstance().getEngine().getMathEngine0()), null);
result = true;
} catch (ParseException e) {
// not valid name;

View File

@ -157,7 +157,7 @@ class VarEditorSaver<T extends MathEntity> implements DialogInterface.OnClickLis
if (!StringUtils.isEmpty(name)) {
try {
assert name != null;
Identifier.parser.parse(Parser.Parameters.newInstance(name, new MutableInt(0), CalculatorLocatorImpl.getInstance().getEngine().getEngine()), null);
Identifier.parser.parse(Parser.Parameters.newInstance(name, new MutableInt(0), CalculatorLocatorImpl.getInstance().getEngine().getMathEngine0()), null);
result = true;
} catch (ParseException e) {
// not valid name;

View File

@ -9,24 +9,21 @@ import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import jscl.*;
import jscl.math.Generic;
import jscl.AngleUnit;
import jscl.JsclMathEngine;
import jscl.MathEngine;
import jscl.NumeralBase;
import jscl.math.function.Function;
import jscl.math.function.IConstant;
import jscl.math.operator.Operator;
import jscl.text.ParseInterruptedException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.*;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.android.calculator.text.TextProcessor;
import org.solovyev.android.msg.AndroidMessage;
import org.solovyev.android.calculator.CalculatorEngine;
import org.solovyev.android.calculator.CalculatorEngineImpl;
import org.solovyev.android.calculator.CalculatorMathEngine;
import org.solovyev.android.calculator.CalculatorMathRegistry;
import org.solovyev.android.prefs.BooleanPreference;
import org.solovyev.android.prefs.Preference;
import org.solovyev.android.prefs.StringPreference;
import org.solovyev.common.MutableObject;
import org.solovyev.common.msg.MessageRegistry;
import org.solovyev.common.msg.MessageType;
import org.solovyev.common.text.EnumMapper;
import org.solovyev.common.text.NumberMapper;
import org.solovyev.common.text.StringUtils;
@ -35,8 +32,6 @@ import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* User: serso
@ -46,270 +41,199 @@ import java.util.concurrent.TimeUnit;
public class AndroidCalculatorEngine implements CalculatorEngine {
private static final String GROUPING_SEPARATOR_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_calc_grouping_separator";
private static final String GROUPING_SEPARATOR_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_calc_grouping_separator";
private static final String MULTIPLICATION_SIGN_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_calc_multiplication_sign";
private static final String MULTIPLICATION_SIGN_DEFAULT = "×";
private static final String MULTIPLICATION_SIGN_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_calc_multiplication_sign";
private static final String MULTIPLICATION_SIGN_DEFAULT = "×";
private static final String MAX_CALCULATION_TIME_P_KEY = "calculation.max_calculation_time";
private static final String MAX_CALCULATION_TIME_DEFAULT = "5";
private static final String MAX_CALCULATION_TIME_P_KEY = "calculation.max_calculation_time";
private static final String MAX_CALCULATION_TIME_DEFAULT = "5";
private static final String SCIENCE_NOTATION_P_KEY = "calculation.output.science_notation";
private static final boolean SCIENCE_NOTATION_DEFAULT = false;
private static final String SCIENCE_NOTATION_P_KEY = "calculation.output.science_notation";
private static final boolean SCIENCE_NOTATION_DEFAULT = false;
private static final String ROUND_RESULT_P_KEY = "org.solovyev.android.calculator.CalculatorModel_round_result";
private static final boolean ROUND_RESULT_DEFAULT = true;
private static final String ROUND_RESULT_P_KEY = "org.solovyev.android.calculator.CalculatorModel_round_result";
private static final boolean ROUND_RESULT_DEFAULT = true;
private static final String RESULT_PRECISION_P_KEY = "org.solovyev.android.calculator.CalculatorModel_result_precision";
private static final String RESULT_PRECISION_DEFAULT = "5";
private static final String RESULT_PRECISION_P_KEY = "org.solovyev.android.calculator.CalculatorModel_result_precision";
private static final String RESULT_PRECISION_DEFAULT = "5";
private static final String NUMERAL_BASES_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_numeral_bases";
private static final String NUMERAL_BASES_DEFAULT = "dec";
private static final String NUMERAL_BASES_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_numeral_bases";
private static final String NUMERAL_BASES_DEFAULT = "dec";
private static final String ANGLE_UNITS_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_angle_units";
private static final String ANGLE_UNITS_DEFAULT = "deg";
private static final String ANGLE_UNITS_P_KEY = "org.solovyev.android.calculator.CalculatorActivity_angle_units";
private static final String ANGLE_UNITS_DEFAULT = "deg";
public static class Preferences {
public static final Preference<String> groupingSeparator = StringPreference.newInstance(GROUPING_SEPARATOR_P_KEY, JsclMathEngine.GROUPING_SEPARATOR_DEFAULT);
public static final Preference<String> multiplicationSign = StringPreference.newInstance(MULTIPLICATION_SIGN_P_KEY, MULTIPLICATION_SIGN_DEFAULT);
public static final Preference<Integer> precision = StringPreference.newInstance(RESULT_PRECISION_P_KEY, RESULT_PRECISION_DEFAULT, new NumberMapper<Integer>(Integer.class));
public static final Preference<Boolean> roundResult = new BooleanPreference(ROUND_RESULT_P_KEY, ROUND_RESULT_DEFAULT);
public static final Preference<NumeralBase> numeralBase = StringPreference.newInstance(NUMERAL_BASES_P_KEY, NUMERAL_BASES_DEFAULT, EnumMapper.newInstance(NumeralBase.class));
public static final Preference<AngleUnit> angleUnit = StringPreference.newInstance(ANGLE_UNITS_P_KEY, ANGLE_UNITS_DEFAULT, EnumMapper.newInstance(AngleUnit.class));
public static final Preference<Boolean> scienceNotation = new BooleanPreference(SCIENCE_NOTATION_P_KEY, SCIENCE_NOTATION_DEFAULT);
public static final Preference<Integer> maxCalculationTime = StringPreference.newInstance(MAX_CALCULATION_TIME_P_KEY, MAX_CALCULATION_TIME_DEFAULT, new NumberMapper<Integer>(Integer.class));
public static class Preferences {
public static final Preference<String> groupingSeparator = StringPreference.newInstance(GROUPING_SEPARATOR_P_KEY, JsclMathEngine.GROUPING_SEPARATOR_DEFAULT);
public static final Preference<String> multiplicationSign = StringPreference.newInstance(MULTIPLICATION_SIGN_P_KEY, MULTIPLICATION_SIGN_DEFAULT);
public static final Preference<Integer> precision = StringPreference.newInstance(RESULT_PRECISION_P_KEY, RESULT_PRECISION_DEFAULT, new NumberMapper<Integer>(Integer.class));
public static final Preference<Boolean> roundResult = new BooleanPreference(ROUND_RESULT_P_KEY, ROUND_RESULT_DEFAULT);
public static final Preference<NumeralBase> numeralBase = StringPreference.newInstance(NUMERAL_BASES_P_KEY, NUMERAL_BASES_DEFAULT, EnumMapper.newInstance(NumeralBase.class));
public static final Preference<AngleUnit> angleUnit = StringPreference.newInstance(ANGLE_UNITS_P_KEY, ANGLE_UNITS_DEFAULT, EnumMapper.newInstance(AngleUnit.class));
public static final Preference<Boolean> scienceNotation = new BooleanPreference(SCIENCE_NOTATION_P_KEY, SCIENCE_NOTATION_DEFAULT);
public static final Preference<Integer> maxCalculationTime = StringPreference.newInstance(MAX_CALCULATION_TIME_P_KEY, MAX_CALCULATION_TIME_DEFAULT, new NumberMapper<Integer>(Integer.class));
private static final List<String> preferenceKeys = new ArrayList<String>();
private static final List<String> preferenceKeys = new ArrayList<String>();
static {
preferenceKeys.add(groupingSeparator.getKey());
preferenceKeys.add(multiplicationSign.getKey());
preferenceKeys.add(precision.getKey());
preferenceKeys.add(roundResult.getKey());
preferenceKeys.add(numeralBase.getKey());
preferenceKeys.add(angleUnit.getKey());
preferenceKeys.add(scienceNotation.getKey());
preferenceKeys.add(maxCalculationTime.getKey());
}
static {
preferenceKeys.add(groupingSeparator.getKey());
preferenceKeys.add(multiplicationSign.getKey());
preferenceKeys.add(precision.getKey());
preferenceKeys.add(roundResult.getKey());
preferenceKeys.add(numeralBase.getKey());
preferenceKeys.add(angleUnit.getKey());
preferenceKeys.add(scienceNotation.getKey());
preferenceKeys.add(maxCalculationTime.getKey());
}
@NotNull
public static List<String> getPreferenceKeys() {
return Collections.unmodifiableList(preferenceKeys);
}
}
@NotNull
private final Object lock = new Object();
@NotNull
private MathEngine engine = JsclMathEngine.instance;
@NotNull
public final TextProcessor<PreparedExpression, String> preprocessor = ToJsclTextProcessor.getInstance();
@NotNull
private final CalculatorMathRegistry<IConstant> varsRegistry;
@NotNull
private final CalculatorMathRegistry<Function> functionsRegistry;
@NotNull
private final CalculatorMathRegistry<Operator> operatorsRegistry;
private final CalculatorMathRegistry<Operator> postfixFunctionsRegistry;
@Nullable
private ThreadKiller threadKiller = new AndroidThreadKiller();
// calculation thread timeout in seconds, after timeout thread would be interrupted
private int timeout = Integer.valueOf(MAX_CALCULATION_TIME_DEFAULT);
@NotNull
private String multiplicationSign = MULTIPLICATION_SIGN_DEFAULT;
@NotNull
public static List<String> getPreferenceKeys() {
return Collections.unmodifiableList(preferenceKeys);
}
}
@NotNull
private final Context context;
public AndroidCalculatorEngine(@NotNull Application application) {
@NotNull
private final CalculatorEngine calculatorEngine;
@NotNull
private final Object lock;
public AndroidCalculatorEngine(@NotNull Application application) {
this.context = application;
this.lock = new Object();
this.engine.setRoundResult(true);
this.engine.setUseGroupingSeparator(true);
this.varsRegistry = new AndroidVarsRegistryImpl(engine.getConstantsRegistry(), application);
this.functionsRegistry = new AndroidFunctionsMathRegistry(engine.getFunctionsRegistry(), application);
this.operatorsRegistry = new AndroidOperatorsMathRegistry(engine.getOperatorsRegistry(), application);
this.postfixFunctionsRegistry = new AndroidPostfixFunctionsRegistry(engine.getPostfixFunctionsRegistry(), application);
final JsclMathEngine engine = JsclMathEngine.instance;
this.calculatorEngine = new CalculatorEngineImpl(engine,
new AndroidVarsRegistryImpl(engine.getConstantsRegistry(), application),
new AndroidFunctionsMathRegistry(engine.getFunctionsRegistry(), application),
new AndroidOperatorsMathRegistry(engine.getOperatorsRegistry(), application),
new AndroidPostfixFunctionsRegistry(engine.getPostfixFunctionsRegistry(), application),
this.lock);
}
@Override
@Override
@NotNull
public String getMultiplicationSign() {
return multiplicationSign;
}
public CalculatorMathRegistry<IConstant> getVarsRegistry() {
return calculatorEngine.getVarsRegistry();
}
public void setMultiplicationSign(@NotNull String multiplicationSign) {
this.multiplicationSign = multiplicationSign;
}
@Override
@NotNull
public CalculatorMathRegistry<Function> getFunctionsRegistry() {
return calculatorEngine.getFunctionsRegistry();
}
public CalculatorOutput evaluate(@NotNull JsclOperation operation,
@NotNull String expression) throws CalculatorParseException, CalculatorEvalException {
return evaluate(operation, expression, null);
}
@Override
@NotNull
public CalculatorMathRegistry<Operator> getOperatorsRegistry() {
return calculatorEngine.getOperatorsRegistry();
}
public CalculatorOutput evaluate(@NotNull final JsclOperation operation,
@NotNull String expression,
@Nullable MessageRegistry mr) throws CalculatorParseException, CalculatorEvalException {
synchronized (lock) {
final StringBuilder sb = new StringBuilder();
@Override
@NotNull
public CalculatorMathRegistry<Operator> getPostfixFunctionsRegistry() {
return calculatorEngine.getPostfixFunctionsRegistry();
}
final PreparedExpression preparedExpression = preprocessor.process(expression);
sb.append(preparedExpression);
@Override
@NotNull
public CalculatorMathEngine getMathEngine() {
return calculatorEngine.getMathEngine();
}
//Log.d(CalculatorEngine.class.getName(), "Preprocessed expression: " + preparedExpression);
/*if (operation == JsclOperation.numeric && preparedExpression.isExistsUndefinedVar()) {
operation = JsclOperation.simplify;
@NotNull
@Override
public MathEngine getMathEngine0() {
return calculatorEngine.getMathEngine0();
}
if (mr != null) {
final String undefinedVars = CollectionsUtils.formatValue(preparedExpression.getUndefinedVars(), ", ", new Formatter<Var>() {
@Override
public String formatValue(@Nullable Var var) throws IllegalArgumentException {
return var != null ? var.getName() : "";
}
});
@NotNull
@Override
public NumeralBase getNumeralBase() {
return calculatorEngine.getNumeralBase();
}
mr.addMessage(new AndroidMessage(R.string.c_simplify_instead_of_numeric, MessageType.info, undefinedVars));
}
}*/
final String jsclExpression = sb.toString();
final MutableObject<Generic> calculationResult = new MutableObject<Generic>(null);
final MutableObject<CalculatorParseException> parseException = new MutableObject<CalculatorParseException>(null);
final MutableObject<CalculatorEvalException> evalException = new MutableObject<CalculatorEvalException>(null);
final MutableObject<Thread> calculationThread = new MutableObject<Thread>(null);
final CountDownLatch latch = new CountDownLatch(1);
new Thread(new Runnable() {
@Override
public void run() {
final Thread thread = Thread.currentThread();
try {
//Log.d(CalculatorEngine.class.getName(), "Calculation thread started work: " + thread.getName());
//System.out.println(jsclExpression);
calculationThread.setObject(thread);
final Generic genericResult = operation.evaluateGeneric(jsclExpression);
// NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!)
genericResult.toString();
calculationResult.setObject(genericResult);
} catch (AbstractJsclArithmeticException e) {
evalException.setObject(new CalculatorEvalException(e, e, jsclExpression));
} catch (ArithmeticException e) {
//System.out.println(e.getMessage());
final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_1, MessageType.error, CalculatorApplication.getInstance(), e.getMessage());
parseException.setObject(new CalculatorParseException(jsclExpression, androidMessage));
} catch (StackOverflowError e) {
//System.out.println(StringUtils.fromStackTrace(e.getStackTrace()));
final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_2, MessageType.error, CalculatorApplication.getInstance());
parseException.setObject(new CalculatorParseException(jsclExpression, androidMessage));
} catch (jscl.text.ParseException e) {
//System.out.println(e.getMessage());
parseException.setObject(new CalculatorParseException(e));
} catch (ParseInterruptedException e) {
//System.out.println(e.getMessage());
// do nothing - we ourselves interrupt the calculations
} finally {
//Log.d(CalculatorEngine.class.getName(), "Calculation thread ended work: " + thread.getName());
calculationThread.setObject(null);
latch.countDown();
}
}
}).start();
try {
//Log.d(CalculatorEngine.class.getName(), "Main thread is waiting: " + Thread.currentThread().getName());
latch.await(timeout, TimeUnit.SECONDS);
//Log.d(CalculatorEngine.class.getName(), "Main thread got up: " + Thread.currentThread().getName());
final CalculatorParseException parseExceptionObject = parseException.getObject();
final CalculatorEvalException evalExceptionObject = evalException.getObject();
final Object calculationResultLocal = calculationResult.getObject();
final Thread calculationThreadLocal = calculationThread.getObject();
if (calculationThreadLocal != null) {
if (threadKiller != null) {
threadKiller.killThread(calculationThreadLocal);
}
//calculationThreadLocal.stop();
}
if (parseExceptionObject != null || evalExceptionObject != null) {
if (operation == JsclOperation.numeric &&
(preparedExpression.isExistsUndefinedVar() || (evalExceptionObject != null && evalExceptionObject.getCause() instanceof NumeralBaseException))) {
return evaluate(JsclOperation.simplify, expression, mr);
}
if (parseExceptionObject != null) {
throw parseExceptionObject;
} else {
throw evalExceptionObject;
}
}
if (calculationResultLocal == null) {
final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_3, MessageType.error, CalculatorApplication.getInstance());
throw new CalculatorParseException(jsclExpression, androidMessage);
}
} catch (InterruptedException e) {
final AndroidMessage androidMessage = new AndroidMessage(R.string.msg_4, MessageType.error, CalculatorApplication.getInstance());
throw new CalculatorParseException(jsclExpression, androidMessage);
}
final Generic genericResult = calculationResult.getObject();
return new CalculatorOutputImpl(operation.getFromProcessor().process(genericResult), operation, genericResult);
}
}
public void setPrecision(int precision) {
this.getEngine().setPrecision(precision);
}
public void setRoundResult(boolean roundResult) {
this.getEngine().setRoundResult(roundResult);
}
@Override
@Override
public void init() {
synchronized (lock) {
reset();
}
}
synchronized (lock) {
calculatorEngine.init();
}
}
@Override
@Override
public void reset() {
synchronized (lock) {
synchronized (lock) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
softReset(preferences);
softReset(preferences);
varsRegistry.load();
functionsRegistry.load();
operatorsRegistry.load();
postfixFunctionsRegistry.load();
}
}
calculatorEngine.reset();
}
}
@Override
@Override
public void softReset() {
synchronized (lock) {
synchronized (lock) {
softReset(PreferenceManager.getDefaultSharedPreferences(context));
}
}
calculatorEngine.softReset();
}
}
@Override
public void setUseGroupingSeparator(boolean useGroupingSeparator) {
calculatorEngine.setUseGroupingSeparator(useGroupingSeparator);
}
@Override
public void setGroupingSeparator(char groupingSeparator) {
calculatorEngine.setGroupingSeparator(groupingSeparator);
}
@Override
public void setPrecision(@NotNull Integer precision) {
calculatorEngine.setPrecision(precision);
}
@Override
public void setRoundResult(@NotNull Boolean round) {
calculatorEngine.setRoundResult(round);
}
@NotNull
@Override
public AngleUnit getAngleUnits() {
return calculatorEngine.getAngleUnits();
}
@Override
public void setAngleUnits(@NotNull AngleUnit angleUnits) {
calculatorEngine.setAngleUnits(angleUnits);
}
@Override
public void setNumeralBase(@NotNull NumeralBase numeralBase) {
calculatorEngine.setNumeralBase(numeralBase);
}
@Override
public void setMultiplicationSign(@NotNull String multiplicationSign) {
calculatorEngine.setMultiplicationSign(multiplicationSign);
}
@Override
public void setScienceNotation(@NotNull Boolean scienceNotation) {
calculatorEngine.setScienceNotation(scienceNotation);
}
@Override
public void setTimeout(@NotNull Integer timeout) {
calculatorEngine.setTimeout(timeout);
}
private void softReset(@NotNull SharedPreferences preferences) {
this.setPrecision(Preferences.precision.getPreference(preferences));
@ -322,100 +246,32 @@ public class AndroidCalculatorEngine implements CalculatorEngine {
final String groupingSeparator = Preferences.groupingSeparator.getPreference(preferences);
if (StringUtils.isEmpty(groupingSeparator)) {
this.getEngine().setUseGroupingSeparator(false);
this.setUseGroupingSeparator(false);
} else {
this.getEngine().setUseGroupingSeparator(true);
this.getEngine().setGroupingSeparator(groupingSeparator.charAt(0));
this.setUseGroupingSeparator(true);
setGroupingSeparator(groupingSeparator.charAt(0));
}
}
@NotNull
public NumeralBase getNumeralBaseFromPrefs(@NotNull SharedPreferences preferences) {
return Preferences.numeralBase.getPreference(preferences);
}
@NotNull
public NumeralBase getNumeralBaseFromPrefs(@NotNull SharedPreferences preferences) {
return Preferences.numeralBase.getPreference(preferences);
}
public AngleUnit getAngleUnitsFromPrefs(@NotNull SharedPreferences preferences) {
return Preferences.angleUnit.getPreference(preferences);
}
@NotNull
public AngleUnit getAngleUnitsFromPrefs(@NotNull SharedPreferences preferences) {
return Preferences.angleUnit.getPreference(preferences);
}
//for tests only
public void setDecimalGroupSymbols(@NotNull DecimalFormatSymbols decimalGroupSymbols) {
this.calculatorEngine.setDecimalGroupSymbols(decimalGroupSymbols);
}
//for tests only
void setDecimalGroupSymbols(@NotNull DecimalFormatSymbols decimalGroupSymbols) {
synchronized (lock) {
this.getEngine().setDecimalGroupSymbols(decimalGroupSymbols);
}
}
@Override
@Override
@NotNull
public CalculatorMathRegistry<IConstant> getVarsRegistry() {
return varsRegistry;
}
public String getMultiplicationSign() {
return calculatorEngine.getMultiplicationSign();
}
@Override
@NotNull
public CalculatorMathRegistry<Function> getFunctionsRegistry() {
return functionsRegistry;
}
@Override
@NotNull
public CalculatorMathRegistry<Operator> getOperatorsRegistry() {
return operatorsRegistry;
}
@Override
@NotNull
public CalculatorMathRegistry<Operator> getPostfixFunctionsRegistry() {
return postfixFunctionsRegistry;
}
@Override
@NotNull
public MathEngine getEngine() {
return engine;
}
// package protected for tests
void setTimeout(int timeout) {
this.timeout = timeout;
}
public void setAngleUnits(@NotNull AngleUnit angleUnits) {
getEngine().setAngleUnits(angleUnits);
}
public void setScienceNotation(boolean scienceNotation) {
getEngine().setScienceNotation(scienceNotation);
}
public void setNumeralBase(@NotNull NumeralBase numeralBase) {
getEngine().setNumeralBase(numeralBase);
}
// for tests only
void setThreadKiller(@Nullable ThreadKiller threadKiller) {
this.threadKiller = threadKiller;
}
private static interface ThreadKiller {
void killThread(@NotNull Thread thread);
}
private static class AndroidThreadKiller implements ThreadKiller {
@Override
public void killThread(@NotNull Thread thread) {
thread.setPriority(Thread.MIN_PRIORITY);
thread.interrupt();
}
}
public static class ThreadKillerImpl implements ThreadKiller {
@Override
public void killThread(@NotNull Thread thread) {
thread.setPriority(Thread.MIN_PRIORITY);
thread.stop();
}
}
}

View File

@ -34,7 +34,7 @@ public class AngleUnitsButton extends DirectionDragButton {
super.initDirectionTextPaint(basePaint, directionTextData, resources);
final TextPaint directionTextPaint = directionTextData.getPaint();
if (CalculatorLocatorImpl.getInstance().getEngine().getEngine().getAngleUnits().name().equals(directionTextData.getText())) {
if (CalculatorLocatorImpl.getInstance().getEngine().getAngleUnits().name().equals(directionTextData.getText())) {
directionTextPaint.setColor(resources.getColor(R.color.selected_angle_unit_text_color));
} else {
directionTextPaint.setColor(resources.getColor(R.color.default_text_color));

View File

@ -37,12 +37,12 @@ public class NumeralBaseConverterDialog {
String value = initialFromValue;
try {
value = ToJsclTextProcessor.getInstance().process(value).getExpression();
b.setFromValue(UnitImpl.newInstance(value, AndroidNumeralBase.valueOf(CalculatorLocatorImpl.getInstance().getEngine().getEngine().getNumeralBase())));
b.setFromValue(UnitImpl.newInstance(value, AndroidNumeralBase.valueOf(CalculatorLocatorImpl.getInstance().getEngine().getNumeralBase())));
} catch (CalculatorParseException e) {
b.setFromValue(UnitImpl.newInstance(value, AndroidNumeralBase.valueOf(CalculatorLocatorImpl.getInstance().getEngine().getEngine().getNumeralBase())));
b.setFromValue(UnitImpl.newInstance(value, AndroidNumeralBase.valueOf(CalculatorLocatorImpl.getInstance().getEngine().getNumeralBase())));
}
} else {
b.setFromValue(UnitImpl.newInstance("", AndroidNumeralBase.valueOf(CalculatorLocatorImpl.getInstance().getEngine().getEngine().getNumeralBase())));
b.setFromValue(UnitImpl.newInstance("", AndroidNumeralBase.valueOf(CalculatorLocatorImpl.getInstance().getEngine().getNumeralBase())));
}
b.setConverter(AndroidNumeralBase.getConverter());
@ -63,7 +63,7 @@ public class NumeralBaseConverterDialog {
public void onClick(@NotNull Unit<String> fromUnits, @NotNull Unit<String> toUnits) {
String toUnitsValue = toUnits.getValue();
if (!toUnits.getUnitType().equals(AndroidNumeralBase.valueOf(CalculatorLocatorImpl.getInstance().getEngine().getEngine().getNumeralBase()))) {
if (!toUnits.getUnitType().equals(AndroidNumeralBase.valueOf(CalculatorLocatorImpl.getInstance().getEngine().getNumeralBase()))) {
toUnitsValue = ((AndroidNumeralBase) toUnits.getUnitType()).getNumeralBase().getJsclPrefix() + toUnitsValue;
}

View File

@ -34,7 +34,7 @@ public class NumeralBasesButton extends DirectionDragButton {
super.initDirectionTextPaint(basePaint, directionTextData, resources);
final TextPaint directionTextPaint = directionTextData.getPaint();
if (CalculatorLocatorImpl.getInstance().getEngine().getEngine().getNumeralBase().name().equals(directionTextData.getText())) {
if (CalculatorLocatorImpl.getInstance().getEngine().getNumeralBase().name().equals(directionTextData.getText())) {
directionTextPaint.setColor(resources.getColor(R.color.selected_angle_unit_text_color));
} else {
directionTextPaint.setColor(resources.getColor(R.color.default_text_color));

View File

@ -6,7 +6,6 @@
package org.solovyev.android.calculator.view;
import jscl.MathContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.*;
@ -30,9 +29,6 @@ public class TextHighlighter implements TextProcessor<TextHighlighter.Result, St
nbFontAttributes.put("color", "#008000");
}
@NotNull
public final MathContext mathContext;
public static class Result implements CharSequence {
@NotNull
@ -76,10 +72,9 @@ public class TextHighlighter implements TextProcessor<TextHighlighter.Result, St
private final int colorBlue;
private final boolean formatNumber;
public TextHighlighter(int baseColor, boolean formatNumber, @NotNull MathContext mathContext) {
public TextHighlighter(int baseColor, boolean formatNumber) {
this.color = baseColor;
this.formatNumber = formatNumber;
this.mathContext = mathContext;
//this.colorRed = Color.red(baseColor);
this.colorRed = (baseColor >> 16) & 0xFF;
//this.colorGreen = Color.green(baseColor);
@ -102,9 +97,9 @@ public class TextHighlighter implements TextProcessor<TextHighlighter.Result, St
final AbstractNumberBuilder numberBuilder;
if (!formatNumber) {
numberBuilder = new LiteNumberBuilder(CalculatorLocatorImpl.getInstance().getEngine().getEngine());
numberBuilder = new LiteNumberBuilder(CalculatorLocatorImpl.getInstance().getEngine());
} else {
numberBuilder = new NumberBuilder(CalculatorLocatorImpl.getInstance().getEngine().getEngine());
numberBuilder = new NumberBuilder(CalculatorLocatorImpl.getInstance().getEngine());
}
for (int i = 0; i < text.length(); i++) {
MathType.Result mathType = MathType.getType(text, i, numberBuilder.isHexMode());

View File

@ -6,7 +6,6 @@
package org.solovyev.android.calculator;
import jscl.JsclMathEngine;
import jscl.MathEngine;
import jscl.NumeralBase;
import junit.framework.Assert;
@ -26,7 +25,7 @@ public class TextHighlighterTest {
@Test
public void testProcess() throws Exception {
TextProcessor<?, String> textHighlighter = new TextHighlighter(0, false, JsclMathEngine.instance);
TextProcessor<?, String> textHighlighter = new TextHighlighter(0, false);
final Random random = new Random(new Date().getTime());
for (int i = 0; i < 1000; i++) {
@ -46,7 +45,7 @@ public class TextHighlighterTest {
Assert.assertEquals(")", textHighlighter.process(")").toString());
Assert.assertEquals(")()(", textHighlighter.process(")()(").toString());
textHighlighter = new TextHighlighter(0, true, JsclMathEngine.instance);
textHighlighter = new TextHighlighter(0, true);
Assert.assertEquals("1 000 000", textHighlighter.process("1000000").toString());
Assert.assertEquals("1 000 000", textHighlighter.process("1000000").toString());
Assert.assertEquals("0.1E3", textHighlighter.process("0.1E3").toString());
@ -65,7 +64,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, false, JsclMathEngine.instance);
textHighlighter = new TextHighlighter(0, false);
textHighlighter.process("cannot calculate 3^10^10 !!!\n" +
" unable to enter 0. FIXED\n" +
@ -92,7 +91,7 @@ public class TextHighlighterTest {
Assert.assertEquals("<b>0x:</b>FF33233FFE", textHighlighter.process("0x:FF33233FFE").toString());
Assert.assertEquals("<b>0x:</b>FF33 233 FFE", textHighlighter.process("0x:FF33 233 FFE").toString());
final MathEngine me = CalculatorLocatorImpl.getInstance().getEngine().getEngine();
final MathEngine me = CalculatorLocatorImpl.getInstance().getEngine().getMathEngine0();
try {
me.setNumeralBase(NumeralBase.hex);
Assert.assertEquals("E", textHighlighter.process("E").toString());

View File

@ -5,25 +5,8 @@
package org.solovyev.android.calculator.model;
import jscl.AngleUnit;
import jscl.JsclMathEngine;
import jscl.NumeralBase;
import jscl.math.Expression;
import jscl.math.Generic;
import jscl.math.function.Constant;
import jscl.math.function.CustomFunction;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.solovyev.android.calculator.CalculatorEvalException;
import org.solovyev.android.calculator.CalculatorLocatorImpl;
import org.solovyev.android.calculator.CalculatorParseException;
import org.solovyev.android.calculator.jscl.JsclOperation;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import static junit.framework.Assert.fail;
/**
* User: serso
@ -37,9 +20,8 @@ public class AndroidCalculatorEngineTest {
public static void setUp() throws Exception {
CalculatorLocatorImpl.getInstance().getEngine().init();
((AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine()).setPrecision(3);
((AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine()).setThreadKiller(new AndroidCalculatorEngine.ThreadKillerImpl());
}
/*
@Test
public void testDegrees() throws Exception {
final AndroidCalculatorEngine cm = (AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine();
@ -95,7 +77,7 @@ public class AndroidCalculatorEngineTest {
}
}
/*final long start = System.currentTimeMillis();
*//*final long start = System.currentTimeMillis();
try {
cm.evaluate(JsclOperation.numeric, "3^10^10^10");
Assert.fail();
@ -106,7 +88,7 @@ public class AndroidCalculatorEngineTest {
} else {
Assert.fail();
}
}*/
}*//*
}
@ -157,7 +139,7 @@ public class AndroidCalculatorEngineTest {
Assert.assertEquals("-2+2.5i", cm.evaluate(JsclOperation.numeric, "-2+2.5i").getStringResult());
Assert.assertEquals("-2+2.1i", cm.evaluate(JsclOperation.numeric, "-2+2.1i").getStringResult());
Assert.assertEquals("-0.1-0.2i", cm.evaluate(JsclOperation.numeric, "(1-i)/(2+6i)").getStringResult());
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "4!").getStringResult());
junit.framework.Assert.assertEquals("24", cm.evaluate(JsclOperation.numeric, "(2+2)!").getStringResult());
junit.framework.Assert.assertEquals("120", cm.evaluate(JsclOperation.numeric, "(2+2+1)!").getStringResult());
@ -230,7 +212,7 @@ public class AndroidCalculatorEngineTest {
Assert.assertEquals("0", cm.evaluate(JsclOperation.numeric, "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))").getStringResult());
/* Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "30°").getResult());
*//* Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "30°").getResult());
Assert.assertEquals("0.524", cm.evaluate(JsclOperation.numeric, "(10+20)°").getResult());
Assert.assertEquals("1.047", cm.evaluate(JsclOperation.numeric, "(10+20)°*2").getResult());
try {
@ -240,14 +222,14 @@ public class AndroidCalculatorEngineTest {
if ( !e.getMessage().equals("Power operation after postfix function is currently unsupported!") ) {
junit.framework.Assert.fail();
}
}*/
}*//*
/* try {
*//* try {
cm.setTimeout(5000);
Assert.assertEquals("2", cm.evaluate(JsclOperation.numeric, "2!").getResult());
} finally {
cm.setTimeout(3000);
}*/
}*//*
CalculatorLocatorImpl.getInstance().getEngine().getVarsRegistry().add(new Var.Builder("t", (String) null));
Assert.assertEquals("2t", cm.evaluate(JsclOperation.simplify, "∂(t^2,t)").getStringResult());
@ -442,5 +424,5 @@ public class AndroidCalculatorEngineTest {
Assert.assertEquals("1/(bln(a))", cm.evaluate(JsclOperation.simplify, "∂(log(a, b), b)").getStringResult());
Assert.assertEquals("-ln(b)/(aln(a)^2)", cm.evaluate(JsclOperation.simplify, "∂(log(a, b), a)").getStringResult());
}
}*/
}

View File

@ -30,7 +30,6 @@ public class NumeralBaseTest {
public static void setUp() throws Exception {
CalculatorLocatorImpl.getInstance().getEngine().init();
((AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine()).setPrecision(3);
((AndroidCalculatorEngine) CalculatorLocatorImpl.getInstance().getEngine()).setThreadKiller(new AndroidCalculatorEngine.ThreadKillerImpl());
}
@Test
@ -100,11 +99,11 @@ public class NumeralBaseTest {
final String bin = "0b:" + line[2].toUpperCase();
final String decExpression = converter.convert(dec);
final String decResult = CalculatorLocatorImpl.getInstance().getEngine().getEngine().evaluate(decExpression);
final String decResult = CalculatorLocatorImpl.getInstance().getEngine().getMathEngine().evaluate(decExpression);
final String hexExpression = converter.convert(hex);
final String hexResult = CalculatorLocatorImpl.getInstance().getEngine().getEngine().evaluate(hexExpression);
final String hexResult = CalculatorLocatorImpl.getInstance().getEngine().getMathEngine().evaluate(hexExpression);
final String binExpression = converter.convert(bin);
final String binResult = CalculatorLocatorImpl.getInstance().getEngine().getEngine().evaluate(binExpression);
final String binResult = CalculatorLocatorImpl.getInstance().getEngine().getMathEngine().evaluate(binExpression);
Assert.assertEquals("dec-hex: " + decExpression + " : " + hexExpression, decResult, hexResult);
Assert.assertEquals("dec-bin: " + decExpression + " : " + binExpression, decResult, binResult);

View File

@ -68,10 +68,10 @@ public class ToJsclTextProcessorTest {
Assert.assertEquals( "EE", preprocessor.process("EE").toString());
try {
CalculatorLocatorImpl.getInstance().getEngine().getEngine().setNumeralBase(NumeralBase.hex);
CalculatorLocatorImpl.getInstance().getEngine().setNumeralBase(NumeralBase.hex);
Assert.assertEquals( "22F*exp(F)", preprocessor.process("22Fexp(F)").toString());
} finally {
CalculatorLocatorImpl.getInstance().getEngine().getEngine().setNumeralBase(NumeralBase.dec);
CalculatorLocatorImpl.getInstance().getEngine().setNumeralBase(NumeralBase.dec);
}
Assert.assertEquals( "0x:ABCDEF", preprocessor.process("0x:ABCDEF").toString());
Assert.assertEquals( "0x:ABCDEF", preprocessor.process("0x:A BC DEF").toString());