This commit is contained in:
serso 2016-02-01 23:15:10 +01:00
parent 8c56dd1083
commit 89680ef544
17 changed files with 158 additions and 164 deletions

View File

@ -28,17 +28,14 @@ import android.text.TextUtils;
import android.util.Log;
import com.squareup.otto.Bus;
import com.squareup.otto.Subscribe;
import jscl.JsclArithmeticException;
import jscl.MathEngine;
import jscl.NumeralBase;
import jscl.NumeralBaseException;
import jscl.*;
import jscl.math.Generic;
import jscl.math.function.Constants;
import jscl.math.function.IConstant;
import jscl.text.ParseInterruptedException;
import org.solovyev.android.calculator.calculations.CalculationCancelledEvent;
import org.solovyev.android.calculator.calculations.CalculationFailedEvent;
import org.solovyev.android.calculator.calculations.CalculationFinishedEvent;
import org.solovyev.android.calculator.errors.FixableErrorsActivity;
import org.solovyev.android.calculator.functions.FunctionsRegistry;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.android.calculator.units.CalculatorNumeralBase;
@ -57,6 +54,7 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@ -65,12 +63,13 @@ import java.util.concurrent.atomic.AtomicLong;
@Singleton
public class Calculator implements CalculatorEventListener, SharedPreferences.OnSharedPreferenceChangeListener {
public static final long NO_SEQUENCE = -1;
private static final long PREFERENCE_CHECK_INTERVAL = TimeUnit.MINUTES.toMillis(15);
@Nonnull
private final CalculatorEventContainer calculatorEventContainer = new ListCalculatorEventContainer();
@Nonnull
private final AtomicLong counter = new AtomicLong(CalculatorUtils.FIRST_ID);
private static final AtomicLong SEQUENCER = new AtomicLong(NO_SEQUENCE);
@Nonnull
private final ToJsclTextProcessor preprocessor = ToJsclTextProcessor.getInstance();
@Nonnull
@ -90,6 +89,8 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
PreferredPreferences preferredPreferences;
@Inject
Editor editor;
@Inject
JsclMathEngine mathEngine;
@Inject
public Calculator(@Nonnull SharedPreferences preferences, @Nonnull Bus bus, @Named(AppModule.THREAD_UI) @Nonnull Executor ui, @Named(AppModule.THREAD_BACKGROUND) @Nonnull Executor background) {
@ -113,7 +114,7 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
String fromString = generic.toString();
if (!Strings.isEmpty(fromString)) {
try {
fromString = ToJsclTextProcessor.getInstance().process(fromString).getExpression();
fromString = ToJsclTextProcessor.getInstance().process(fromString).getValue();
} catch (ParseException e) {
// ok, problems while processing occurred
}
@ -130,19 +131,19 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
@Nonnull
private CalculatorEventData nextEventData() {
long eventId = counter.incrementAndGet();
final long eventId = nextSequence();
return CalculatorEventDataImpl.newInstance(eventId, eventId);
}
@Nonnull
private CalculatorEventData nextEventData(@Nonnull Object source) {
long eventId = counter.incrementAndGet();
long eventId = nextSequence();
return CalculatorEventDataImpl.newInstance(eventId, eventId, source);
}
@Nonnull
private CalculatorEventData nextEventData(@Nonnull Long sequenceId) {
long eventId = counter.incrementAndGet();
long eventId = nextSequence();
return CalculatorEventDataImpl.newInstance(eventId, sequenceId);
}
@ -167,7 +168,7 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
background.execute(new Runnable() {
@Override
public void run() {
Calculator.this.evaluateAsync(eventDataId.getSequenceId(), operation, expression, null);
evaluateAsync(eventDataId.getSequenceId(), operation, expression);
}
});
@ -181,7 +182,7 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
background.execute(new Runnable() {
@Override
public void run() {
evaluateAsync(eventDataId.getSequenceId(), operation, expression, null);
evaluateAsync(eventDataId.getSequenceId(), operation, expression);
}
});
@ -215,70 +216,73 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
return CalculatorConversionEventDataImpl.newInstance(nextEventData(sequenceId), value, from, to, displayViewState);
}
private void evaluateAsync(long sequence,
@Nonnull JsclOperation operation,
@Nonnull String expression,
@Nullable MessageRegistry mr) {
checkPreferredPreferences();
expression = expression.trim();
private void evaluateAsync(long sequence, @Nonnull JsclOperation o, @Nonnull String e) {
evaluateAsync(sequence, o, e, new ListMessageRegistry());
}
PreparedExpression preparedExpression = null;
try {
if (Strings.isEmpty(expression)) {
bus.post(new CalculationFinishedEvent(operation, expression, sequence));
private void evaluateAsync(long sequence,
@Nonnull JsclOperation o,
@Nonnull String e,
@Nonnull MessageRegistry mr) {
e = e.trim();
if (Strings.isEmpty(e)) {
bus.post(new CalculationFinishedEvent(o, e, sequence));
return;
}
preparedExpression = prepareExpression(expression);
final String jsclExpression = preparedExpression.toString();
checkPreferredPreferences();
PreparedExpression pe = null;
try {
pe = prepare(e);
try {
final MathEngine mathEngine = Locator.getInstance().getEngine().getMathEngine();
Locator.getInstance().getEngine().getMathEngine().setMessageRegistry(mr);
final MessageRegistry messageRegistry = new ListMessageRegistry();
Locator.getInstance().getEngine().getMathEngine().setMessageRegistry(messageRegistry);
final Generic result = operation.evaluateGeneric(jsclExpression, mathEngine);
final Generic result = o.evaluateGeneric(pe.value, mathEngine);
// NOTE: toString() method must be called here as ArithmeticOperationException may occur in it (just to avoid later check!)
//noinspection ResultOfMethodCallIgnored
result.toString();
if (messageRegistry.hasMessage()) {
final String stringResult = o.getFromProcessor().process(result);
bus.post(new CalculationFinishedEvent(o, e, sequence, result, stringResult, collectMessages(mr)));
} catch (JsclArithmeticException exception) {
if (o == JsclOperation.numeric && exception.getCause() instanceof NumeralBaseException) {
evaluateAsync(sequence, JsclOperation.simplify, e, mr);
} else {
bus.post(new CalculationFailedEvent(o, e, sequence, exception));
}
}
} catch (ArithmeticException exception) {
onException(sequence, o, e, mr, pe, new ParseException(e, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, exception.getMessage())));
} catch (StackOverflowError exception) {
onException(sequence, o, e, mr, pe, new ParseException(e, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error)));
} catch (jscl.text.ParseException exception) {
onException(sequence, o, e, mr, pe, new ParseException(exception));
} catch (ParseInterruptedException exception) {
bus.post(new CalculationCancelledEvent(o, e, sequence));
} catch (ParseException exception) {
onException(sequence, o, e, mr, pe, exception);
}
}
@Nonnull
private List<Message> collectMessages(@Nonnull MessageRegistry mr) {
if (mr.hasMessage()) {
try {
final List<Message> messages = new ArrayList<>();
while (messageRegistry.hasMessage()) {
messages.add(messageRegistry.getMessage());
while (mr.hasMessage()) {
messages.add(mr.getMessage());
}
if (!messages.isEmpty()) {
fireCalculatorEvent(newCalculationEventData(operation, expression, sequence), CalculatorEventType.calculation_messages, messages);
}
} catch (Throwable e) {
// todo serso: not good but we need proper synchronization
Log.e("Calculator", e.getMessage(), e);
return messages;
} catch (Throwable exception) {
// several threads might use the same instance of MessageRegistry, as no proper synchronization is done
// catch Throwable here
Log.e("Calculator", exception.getMessage(), exception);
}
}
final String stringResult = operation.getFromProcessor().process(result);
bus.post(new CalculationFinishedEvent(operation, expression, sequence, result, stringResult));
} catch (JsclArithmeticException e) {
if (operation == JsclOperation.numeric && e.getCause() instanceof NumeralBaseException) {
evaluateAsync(sequence, JsclOperation.simplify, expression, mr);
} else {
bus.post(new CalculationFailedEvent(operation, expression, sequence, e));
}
}
} catch (ArithmeticException e) {
handleException(sequence, operation, expression, mr, preparedExpression, new ParseException(expression, new CalculatorMessage(CalculatorMessages.msg_001, MessageType.error, e.getMessage())));
} catch (StackOverflowError e) {
handleException(sequence, operation, expression, mr, preparedExpression, new ParseException(expression, new CalculatorMessage(CalculatorMessages.msg_002, MessageType.error)));
} catch (jscl.text.ParseException e) {
handleException(sequence, operation, expression, mr, preparedExpression, new ParseException(e));
} catch (ParseInterruptedException e) {
bus.post(new CalculationCancelledEvent(operation, expression, sequence));
} catch (ParseException e) {
handleException(sequence, operation, expression, mr, preparedExpression, e);
}
return Collections.emptyList();
}
private void checkPreferredPreferences() {
@ -298,30 +302,23 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
}
@Nonnull
public PreparedExpression prepareExpression(@Nonnull String expression) throws ParseException {
public PreparedExpression prepare(@Nonnull String expression) throws ParseException {
return preprocessor.process(expression);
}
@Nonnull
private CalculatorEventData newCalculationEventData(@Nonnull JsclOperation operation,
@Nonnull String expression,
@Nonnull Long calculationId) {
return new CalculatorEvaluationEventDataImpl(nextEventData(calculationId), operation, expression);
}
private void handleException(long sequence,
private void onException(long sequence,
@Nonnull JsclOperation operation,
@Nonnull String expression,
@Nullable MessageRegistry mr,
@Nullable PreparedExpression preparedExpression,
@Nonnull String e,
@Nonnull MessageRegistry mr,
@Nullable PreparedExpression pe,
@Nonnull ParseException parseException) {
if (operation == JsclOperation.numeric
&& preparedExpression != null
&& preparedExpression.isExistsUndefinedVar()) {
evaluateAsync(sequence, JsclOperation.simplify, expression, mr);
} else {
bus.post(new CalculationFailedEvent(operation, expression, sequence, parseException));
&& pe != null
&& pe.hasUndefinedVariables()) {
evaluateAsync(sequence, JsclOperation.simplify, e, mr);
return;
}
bus.post(new CalculationFailedEvent(operation, e, sequence, parseException));
}
@Nonnull
@ -423,9 +420,9 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
private void updateAnsVariable(@NonNull String value) {
final VariablesRegistry variablesRegistry = Locator.getInstance().getEngine().getVariablesRegistry();
final IConstant variable = variablesRegistry.get(VariablesRegistry.ANS);
final IConstant variable = variablesRegistry.get(Constants.ANS);
final CppVariable.Builder b = variable != null ? CppVariable.builder(variable) : CppVariable.builder(VariablesRegistry.ANS);
final CppVariable.Builder b = variable != null ? CppVariable.builder(variable) : CppVariable.builder(Constants.ANS);
b.withValue(value);
b.withSystem(true);
b.withDescription(CalculatorMessages.getBundle().getString(CalculatorMessages.ans_description));
@ -460,7 +457,7 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
@Subscribe
public void onVariableChanged(@NonNull VariablesRegistry.ChangedEvent e) {
if (!e.newVariable.getName().equals(VariablesRegistry.ANS)) {
if (!e.newVariable.getName().equals(Constants.ANS)) {
evaluate();
}
}
@ -468,9 +465,6 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
@Override
public void onCalculatorEvent(@Nonnull CalculatorEventData calculatorEventData, @Nonnull CalculatorEventType calculatorEventType, @Nullable Object data) {
switch (calculatorEventType) {
case calculation_messages:
FixableErrorsActivity.show(App.getApplication(), (List<Message>) data);
break;
case show_history:
ActivityLauncher.showHistory(App.getApplication());
break;
@ -520,4 +514,7 @@ public class Calculator implements CalculatorEventListener, SharedPreferences.On
}
}
public static long nextSequence() {
return SEQUENCER.incrementAndGet();
}
}

View File

@ -22,15 +22,14 @@
package org.solovyev.android.calculator;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nonnull;
import jscl.math.Generic;
import jscl.math.function.Constant;
import jscl.math.function.IConstant;
import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.Set;
/**
* User: serso
* Date: 9/22/12
@ -38,15 +37,13 @@ import jscl.math.function.IConstant;
*/
public final class CalculatorUtils {
static final long FIRST_ID = 0;
private CalculatorUtils() {
throw new AssertionError();
}
@Nonnull
public static CalculatorEventData createFirstEventDataId() {
return CalculatorEventDataImpl.newInstance(FIRST_ID, FIRST_ID);
return CalculatorEventDataImpl.newInstance(Calculator.NO_SEQUENCE, Calculator.NO_SEQUENCE);
}
@Nonnull

View File

@ -22,6 +22,8 @@
package org.solovyev.android.calculator;
import android.app.Application;
import android.content.Context;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
@ -33,6 +35,7 @@ import org.solovyev.android.Check;
import org.solovyev.android.calculator.calculations.CalculationCancelledEvent;
import org.solovyev.android.calculator.calculations.CalculationFailedEvent;
import org.solovyev.android.calculator.calculations.CalculationFinishedEvent;
import org.solovyev.android.calculator.errors.FixableErrorsActivity;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.android.calculator.view.NumeralBaseConverterDialog;
@ -53,6 +56,8 @@ public class Display implements CalculatorEventListener, View.OnClickListener, V
@Nonnull
private final Bus bus;
@Inject
Application application;
@Inject
Lazy<Keyboard> keyboard;
@Inject
Lazy<Clipboard> clipboard;
@ -84,6 +89,10 @@ public class Display implements CalculatorEventListener, View.OnClickListener, V
public void onCalculationFinished(@Nonnull CalculationFinishedEvent e) {
if (e.sequence < state.sequence) return;
setState(DisplayState.createValid(e.operation, e.result, e.stringResult, e.sequence));
if (!e.messages.isEmpty()) {
final Context context = view != null ? view.getContext() : application;
FixableErrorsActivity.show(context, e.messages);
}
}
@Subscribe

View File

@ -64,18 +64,18 @@ public class DisplayState implements Parcelable, ContextMenu.ContextMenuInfo {
}
DisplayState(@Nonnull JSONObject json) {
this(json.optString(JSON_TEXT), true, EditorState.NO_SEQUENCE);
this(json.optString(JSON_TEXT), true, Calculator.NO_SEQUENCE);
}
private DisplayState(Parcel in) {
text = in.readString();
valid = in.readByte() != 0;
sequence = EditorState.NO_SEQUENCE;
sequence = Calculator.NO_SEQUENCE;
}
@Nonnull
public static DisplayState empty() {
return new DisplayState("", true, EditorState.NO_SEQUENCE);
return new DisplayState("", true, Calculator.NO_SEQUENCE);
}
@Nonnull

View File

@ -25,18 +25,14 @@ package org.solovyev.android.calculator;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class EditorState implements Parcelable {
public static final long NO_SEQUENCE = -1;
public static final Creator<EditorState> CREATOR = new Creator<EditorState>() {
@Override
public EditorState createFromParcel(Parcel in) {
@ -50,7 +46,6 @@ public class EditorState implements Parcelable {
};
private static final String JSON_TEXT = "t";
private static final String JSON_SELECTION = "s";
private static AtomicLong counter = new AtomicLong(NO_SEQUENCE + 1);
public final long sequence;
@Nonnull
public final CharSequence text;
@ -63,7 +58,7 @@ public class EditorState implements Parcelable {
}
private EditorState(@Nonnull CharSequence text, int selection) {
this.sequence = counter.getAndIncrement();
this.sequence = Calculator.nextSequence();
this.text = text;
this.selection = selection;
}
@ -73,7 +68,7 @@ public class EditorState implements Parcelable {
}
private EditorState(Parcel in) {
sequence = NO_SEQUENCE;
sequence = Calculator.NO_SEQUENCE;
selection = in.readInt();
textString = in.readString();
text = textString;

View File

@ -31,48 +31,43 @@ import java.util.List;
public class PreparedExpression implements CharSequence {
@Nonnull
private String expression;
public final String value;
@Nonnull
private List<IConstant> undefinedVars;
public final List<IConstant> undefinedVariables;
public PreparedExpression(@Nonnull String expression, @Nonnull List<IConstant> undefinedVars) {
this.expression = expression;
this.undefinedVars = undefinedVars;
public PreparedExpression(@Nonnull String value, @Nonnull List<IConstant> undefinedVariables) {
this.value = value;
this.undefinedVariables = undefinedVariables;
}
@Nonnull
public String getExpression() {
return expression;
public String getValue() {
return value;
}
public boolean isExistsUndefinedVar() {
return !this.undefinedVars.isEmpty();
}
@Nonnull
public List<IConstant> getUndefinedVars() {
return undefinedVars;
public boolean hasUndefinedVariables() {
return !undefinedVariables.isEmpty();
}
@Override
public int length() {
return expression.length();
return value.length();
}
@Override
public char charAt(int i) {
return expression.charAt(i);
return value.charAt(i);
}
@Override
public CharSequence subSequence(int i, int i1) {
return expression.subSequence(i, i1);
return value.subSequence(i, i1);
}
@NonNull
@Override
public String toString() {
return this.expression;
return this.value;
}
}

View File

@ -52,9 +52,6 @@ import java.util.Map;
@Singleton
public class VariablesRegistry extends BaseEntitiesRegistry<IConstant> {
@Nonnull
public static final String ANS = "ans";
@Nonnull
private static final Map<String, String> substitutes = new HashMap<>();

View File

@ -2,25 +2,32 @@ package org.solovyev.android.calculator.calculations;
import jscl.math.Generic;
import org.solovyev.android.calculator.jscl.JsclOperation;
import org.solovyev.common.msg.Message;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
public final class CalculationFinishedEvent extends BaseCalculationEvent {
@Nullable
public final Generic result;
@Nonnull
public final String stringResult;
@Nonnull
public final List<Message> messages;
public CalculationFinishedEvent(@Nonnull JsclOperation operation, @Nonnull String expression, long sequence) {
super(operation, expression, sequence);
result = null;
stringResult = "";
messages = Collections.emptyList();
}
public CalculationFinishedEvent(@Nonnull JsclOperation operation, @Nonnull String expression, long sequence, @Nullable Generic result, @Nonnull String stringResult) {
public CalculationFinishedEvent(@Nonnull JsclOperation operation, @Nonnull String expression, long sequence, @Nullable Generic result, @Nonnull String stringResult, @Nonnull List<Message> messages) {
super(operation, expression, sequence);
this.result = result;
this.stringResult = stringResult;
this.messages = messages;
}
}

View File

@ -271,7 +271,7 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
private boolean applyData() {
try {
final String body = calculator.prepareExpression(bodyView.getText().toString()).getExpression();
final String body = calculator.prepare(bodyView.getText().toString()).getValue();
final CppFunction newFunction = CppFunction.builder(nameView.getText().toString(), body)
.withId(isNewFunction() ? NO_ID : function.id)
@ -326,7 +326,7 @@ public class EditFunctionFragment extends BaseDialogFragment implements View.OnC
return false;
}
try {
calculator.prepareExpression(body);
calculator.prepare(body);
clearError(bodyLabel);
return true;
} catch (ParseException e) {

View File

@ -100,7 +100,7 @@ public class History {
final OldDisplayHistoryState oldDisplay = state.getDisplayState();
final String editorText = oldEditor.getText();
final EditorState editor = EditorState.create(Strings.nullToEmpty(editorText), oldEditor.getCursorPosition());
final DisplayState display = DisplayState.createValid(oldDisplay.getJsclOperation(), null, Strings.nullToEmpty(oldDisplay.getEditorState().getText()), EditorState.NO_SEQUENCE);
final DisplayState display = DisplayState.createValid(oldDisplay.getJsclOperation(), null, Strings.nullToEmpty(oldDisplay.getEditorState().getText()), Calculator.NO_SEQUENCE);
states.add(HistoryState.builder(editor, display).withTime(state.getTime()).withComment(state.getComment()).build());
}
return states;

View File

@ -61,9 +61,8 @@ public class VariablesFragment extends BaseEntitiesFragment<IConstant> {
public static boolean isValidValue(@Nonnull String value) {
try {
final PreparedExpression expression = ToJsclTextProcessor.getInstance().process(value);
final List<IConstant> variables = expression.getUndefinedVars();
return variables.isEmpty();
final PreparedExpression pe = ToJsclTextProcessor.getInstance().process(value);
return !pe.hasUndefinedVariables();
} catch (RuntimeException e) {
return false;
}

View File

@ -57,7 +57,7 @@ public class NumeralBaseConverterDialog {
if (!Strings.isEmpty(initialFromValue)) {
String value = initialFromValue;
try {
value = ToJsclTextProcessor.getInstance().process(value).getExpression();
value = ToJsclTextProcessor.getInstance().process(value).getValue();
b.setFromValue(UnitImpl.newInstance(value, CalculatorNumeralBase.valueOf(Locator.getInstance().getEngine().getMathEngine().getNumeralBase())));
} catch (ParseException e) {
b.setFromValue(UnitImpl.newInstance(value, CalculatorNumeralBase.valueOf(Locator.getInstance().getEngine().getMathEngine().getNumeralBase())));

View File

@ -90,7 +90,7 @@ public class AndroidEngineTest extends AbstractCalculatorTest {
}
@Test
public void testI() throws ParseException, EvalException {
public void testI() throws ParseException {
final MathEngine cm = Locator.getInstance().getEngine().getMathEngine();
CalculatorTestUtils.assertEval("-i", cm.evaluate("i^3"));

View File

@ -22,26 +22,24 @@
package org.solovyev.android.calculator.model;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.solovyev.android.calculator.AbstractCalculatorTest;
import org.solovyev.android.calculator.ParseException;
import org.solovyev.android.calculator.CalculatorTestUtils;
import org.solovyev.android.calculator.Locator;
import org.solovyev.common.Converter;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
import au.com.bytecode.opencsv.CSVReader;
import jscl.JsclMathEngine;
import jscl.MathEngine;
import jscl.math.Expression;
import jscl.util.ExpressionGeneratorWithInput;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.solovyev.android.calculator.AbstractCalculatorTest;
import org.solovyev.android.calculator.CalculatorTestUtils;
import org.solovyev.android.calculator.Locator;
import org.solovyev.android.calculator.ParseException;
import org.solovyev.common.Converter;
import javax.annotation.Nonnull;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
/**
* User: serso
@ -56,7 +54,7 @@ public class NumeralBaseTest extends AbstractCalculatorTest {
Locator.getInstance().getEngine().getMathEngine().setPrecision(3);
}
public static void testExpression(@Nonnull String[] line, @Nonnull Converter<String, String> converter) throws jscl.text.ParseException, EvalException, ParseException {
public static void testExpression(@Nonnull String[] line, @Nonnull Converter<String, String> converter) throws jscl.text.ParseException, ParseException {
final String dec = line[0].toUpperCase();
final String hex = "0x:" + line[1].toUpperCase();
final String bin = "0b:" + line[2].toUpperCase();

View File

@ -149,7 +149,7 @@ public class ToJsclTextProcessorTest extends AbstractCalculatorTest {
Assert.assertEquals("101", JsclMathEngine.getInstance().evaluate("10+11"));
JsclMathEngine.getInstance().setNumeralBase(NumeralBase.hex);
Assert.assertEquals("56CE+CAD", processor.process("56CE+CAD").getExpression());
Assert.assertEquals("56CE+CAD", processor.process("56CE+CAD").getValue());
} finally {
JsclMathEngine.getInstance().setNumeralBase(defaultNumeralBase);
}

View File

@ -16,7 +16,6 @@ import org.solovyev.common.msg.MessageRegistry;
import org.solovyev.common.msg.Messages;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
@ -168,20 +167,17 @@ public class JsclMathEngine implements MathEngine {
// detect if current number is precisely equals to constant in constants' registry (NOTE: ONLY FOR SYSTEM CONSTANTS)
final Double localValue = value;
IConstant constant = Collections.find(this.getConstantsRegistry().getSystemEntities(), new JPredicate<IConstant>() {
public boolean apply(@Nullable IConstant constant) {
if (constant != null) {
if (localValue.equals(constant.getDoubleValue())) {
if (!constant.getName().equals(Constants.PI_INV.getName())) {
if (!constant.getName().equals(Constants.PI.getName()) || JsclMathEngine.getInstance().getAngleUnits() == AngleUnit.rad) {
return true;
}
}
}
}
IConstant constant = Collections.find(getConstantsRegistry().getSystemEntities(), new JPredicate<IConstant>() {
public boolean apply(@Nonnull IConstant constant) {
if (!localValue.equals(constant.getDoubleValue())) {
return false;
}
final String name = constant.getName();
if (name.equals(Constants.PI_INV.getName()) || name.equals(Constants.ANS)) {
return false;
}
return !name.equals(Constants.PI.getName()) || JsclMathEngine.getInstance().getAngleUnits() == AngleUnit.rad;
}
});

View File

@ -2,6 +2,8 @@ package jscl.math.function;
import jscl.math.JsclInteger;
import javax.annotation.Nonnull;
/**
* User: serso
* Date: 1/7/12
@ -14,6 +16,8 @@ public final class Constants {
public static final Constant I = new Constant("i");
public static final Constant INF = new Constant("");
public static final Constant INF_2 = new Constant("Infinity");
@Nonnull
public static final String ANS = "ans";
// not intended for instantiation
private Constants() {