complex number support added
This commit is contained in:
parent
5d4c42a0e7
commit
4d0ed38088
22
pom.xml
22
pom.xml
@ -15,8 +15,24 @@
|
|||||||
<additionalLibs>${basedir}/src/misc/lib</additionalLibs>
|
<additionalLibs>${basedir}/src/misc/lib</additionalLibs>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>congrace.de</id>
|
||||||
|
<name>releases</name>
|
||||||
|
<url>http://nexus.congrace.de/nexus/content/repositories/releases/</url>
|
||||||
|
<layout>default</layout>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.8.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.solovyev</groupId>
|
<groupId>org.solovyev</groupId>
|
||||||
<artifactId>common</artifactId>
|
<artifactId>common</artifactId>
|
||||||
@ -37,6 +53,12 @@
|
|||||||
<systemPath>${additionalLibs}/jscl.jar</systemPath>
|
<systemPath>${additionalLibs}/jscl.jar</systemPath>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.congrace</groupId>
|
||||||
|
<artifactId>exp4j</artifactId>
|
||||||
|
<version>0.2.8</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.intellij</groupId>
|
<groupId>com.intellij</groupId>
|
||||||
<artifactId>annotations</artifactId>
|
<artifactId>annotations</artifactId>
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
style="@style/control_button_style"
|
style="@style/control_button_style"
|
||||||
a:onClick="eraseButtonClickHandler"/>
|
a:onClick="eraseButtonClickHandler"/>
|
||||||
|
|
||||||
<TextView
|
<org.solovyev.android.calculator.CalculatorDisplay
|
||||||
a:id="@+id/resultEditText"
|
a:id="@+id/resultEditText"
|
||||||
style="@style/display_style"
|
style="@style/display_style"
|
||||||
a:gravity="right|top"
|
a:gravity="right|top"
|
||||||
@ -75,8 +75,8 @@
|
|||||||
calc:textDown="acos" style="@style/digit_button_style"
|
calc:textDown="acos" style="@style/digit_button_style"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/threeDigitButton" a:text="3" calc:textUp="tg"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/threeDigitButton" a:text="3" calc:textUp="tan"
|
||||||
calc:textDown="atg" style="@style/digit_button_style"
|
calc:textDown="atan" style="@style/digit_button_style"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/multiplicationButton" a:text="×"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/multiplicationButton" a:text="×"
|
||||||
@ -106,20 +106,22 @@
|
|||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/fourDigitButton"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/fourDigitButton"
|
||||||
a:text="4"
|
a:text="4"
|
||||||
calc:textUp=""
|
calc:textUp="sinh"
|
||||||
calc:textDown=""
|
calc:textDown="asinh"
|
||||||
style="@style/digit_button_style"
|
style="@style/digit_button_style"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/fiveDigitButton"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/fiveDigitButton"
|
||||||
a:text="5"
|
a:text="5"
|
||||||
calc:textUp="ln"
|
calc:textUp="cosh"
|
||||||
|
calc:textDown="acosh"
|
||||||
style="@style/digit_button_style"
|
style="@style/digit_button_style"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/sixDigitButton" a:text="6"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/sixDigitButton" a:text="6"
|
||||||
calc:textUp=""
|
calc:textUp="tanh"
|
||||||
calc:textDown="" style="@style/digit_button_style"
|
calc:textDown="atanh"
|
||||||
|
style="@style/digit_button_style"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/plusButton" a:text="+"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/plusButton" a:text="+"
|
||||||
@ -147,12 +149,16 @@
|
|||||||
|
|
||||||
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
|
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/sevenDigitButton" a:text="7" calc:textUp=""
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/sevenDigitButton" a:text="7"
|
||||||
calc:textDown="" style="@style/digit_button_style"
|
calc:textUp="i"
|
||||||
|
calc:textDown=""
|
||||||
|
style="@style/digit_button_style"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/eightDigitButton" a:text="8" calc:textUp=""
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/eightDigitButton" a:text="8"
|
||||||
calc:textDown="" style="@style/digit_button_style"
|
calc:textUp="ln"
|
||||||
|
calc:textDown=""
|
||||||
|
style="@style/digit_button_style"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/nineDigitButton" a:text="9"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/nineDigitButton" a:text="9"
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
style="@style/control_button_style"
|
style="@style/control_button_style"
|
||||||
a:onClick="numericButtonClickHandler"/>
|
a:onClick="numericButtonClickHandler"/>
|
||||||
|
|
||||||
<TextView
|
<org.solovyev.android.calculator.CalculatorDisplay
|
||||||
a:id="@+id/resultEditText"
|
a:id="@+id/resultEditText"
|
||||||
style="@style/display_style"
|
style="@style/display_style"
|
||||||
a:gravity="right|top"
|
a:gravity="right|top"
|
||||||
@ -56,8 +56,8 @@
|
|||||||
calc:textDown="acos" style="@style/digit_button_style"
|
calc:textDown="acos" style="@style/digit_button_style"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/threeDigitButton" a:text="3" calc:textUp="tg"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/threeDigitButton" a:text="3" calc:textUp="tan"
|
||||||
calc:textDown="atg" style="@style/digit_button_style"
|
calc:textDown="atan" style="@style/digit_button_style"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/multiplicationButton" a:text="×"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/multiplicationButton" a:text="×"
|
||||||
@ -76,20 +76,22 @@
|
|||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/fourDigitButton"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/fourDigitButton"
|
||||||
a:text="4"
|
a:text="4"
|
||||||
calc:textUp=""
|
calc:textUp="sinh"
|
||||||
calc:textDown=""
|
calc:textDown="asinh"
|
||||||
style="@style/digit_button_style"
|
style="@style/digit_button_style"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/fiveDigitButton"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/fiveDigitButton"
|
||||||
a:text="5"
|
a:text="5"
|
||||||
calc:textUp="ln"
|
calc:textUp="cosh"
|
||||||
|
calc:textDown="acosh"
|
||||||
style="@style/digit_button_style"
|
style="@style/digit_button_style"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/sixDigitButton" a:text="6"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/sixDigitButton" a:text="6"
|
||||||
calc:textUp=""
|
calc:textUp="tanh"
|
||||||
calc:textDown="" style="@style/digit_button_style"
|
calc:textDown="atanh"
|
||||||
|
style="@style/digit_button_style"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/divisionButton" a:text="/"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/divisionButton" a:text="/"
|
||||||
@ -106,12 +108,16 @@
|
|||||||
|
|
||||||
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
|
<LinearLayout a:layout_weight="1" a:layout_width="match_parent" a:layout_height="0dp">
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/sevenDigitButton" a:text="7" calc:textUp=""
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/sevenDigitButton" a:text="7"
|
||||||
calc:textDown="" style="@style/digit_button_style"
|
calc:textUp="i"
|
||||||
|
calc:textDown=""
|
||||||
|
style="@style/digit_button_style"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/eightDigitButton" a:text="8" calc:textUp=""
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/eightDigitButton" a:text="8"
|
||||||
calc:textDown="" style="@style/digit_button_style"
|
calc:textUp="ln"
|
||||||
|
calc:textDown=""
|
||||||
|
style="@style/digit_button_style"
|
||||||
a:onClick="digitButtonClickHandler"/>
|
a:onClick="digitButtonClickHandler"/>
|
||||||
|
|
||||||
<org.solovyev.android.view.DirectionDragButton a:id="@+id/nineDigitButton" a:text="9"
|
<org.solovyev.android.view.DirectionDragButton a:id="@+id/nineDigitButton" a:text="9"
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="c_app_name">Calculator</string>
|
<string name="c_app_name">Calculator</string>
|
||||||
<string name="c_app_settings">Calculator</string>
|
<string name="c_app_settings">Calculator</string>
|
||||||
<string name="syntax_error">Syntax error</string>
|
<string name="c_syntax_error">Syntax error</string>
|
||||||
|
<string name="c_result_copied">Result copied to clipboard!</string>
|
||||||
<string name="c_settings">Settings</string>
|
<string name="c_settings">Settings</string>
|
||||||
<string name="c_help">Help</string>
|
<string name="c_help">Help</string>
|
||||||
<string name="c_prefs_main_category">Main settings</string>
|
<string name="c_prefs_main_category">Main settings</string>
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="display_style">
|
<style name="display_style">
|
||||||
<item name="android:textSize">30dp</item>
|
<item name="android:textSize">25dp</item>
|
||||||
<item name="android:background">#000000</item>
|
<item name="android:background">#000000</item>
|
||||||
<item name="android:textColor">#ffffff</item>
|
<item name="android:textColor">#ffffff</item>
|
||||||
<item name="android:gravity">left|top</item>
|
<item name="android:gravity">left|top</item>
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||||
|
* For more information, please, contact se.solovyev@gmail.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: serso
|
||||||
|
* Date: 9/17/11
|
||||||
|
* Time: 10:58 PM
|
||||||
|
*/
|
||||||
|
public class CalculatorDisplay extends TextView {
|
||||||
|
|
||||||
|
private boolean valid = true;
|
||||||
|
|
||||||
|
public CalculatorDisplay(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CalculatorDisplay(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CalculatorDisplay(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValid(boolean valid) {
|
||||||
|
this.valid = valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setText(CharSequence text, BufferType type) {
|
||||||
|
super.setText(text, type);
|
||||||
|
|
||||||
|
setValid(true);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||||
|
* For more information, please, contact se.solovyev@gmail.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: serso
|
||||||
|
* Date: 9/17/11
|
||||||
|
* Time: 11:05 PM
|
||||||
|
*/
|
||||||
|
public class CalculatorDisplayHistoryState extends EditorHistoryState {
|
||||||
|
|
||||||
|
private boolean valid = true;
|
||||||
|
|
||||||
|
public CalculatorDisplayHistoryState() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public CalculatorDisplayHistoryState(boolean valid) {
|
||||||
|
this.valid = valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CalculatorDisplayHistoryState(int cursorPosition, @Nullable String text, boolean valid) {
|
||||||
|
super(cursorPosition, text);
|
||||||
|
this.valid = valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValid(boolean valid) {
|
||||||
|
this.valid = valid;
|
||||||
|
}
|
||||||
|
}
|
@ -18,9 +18,9 @@ public class CalculatorHistoryState {
|
|||||||
private EditorHistoryState editorState;
|
private EditorHistoryState editorState;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private EditorHistoryState displayState;
|
private CalculatorDisplayHistoryState displayState;
|
||||||
|
|
||||||
public CalculatorHistoryState(@NotNull EditorHistoryState editorState, @NotNull EditorHistoryState displayState) {
|
public CalculatorHistoryState(@NotNull EditorHistoryState editorState, @NotNull CalculatorDisplayHistoryState displayState) {
|
||||||
this.editorState = editorState;
|
this.editorState = editorState;
|
||||||
this.displayState = displayState;
|
this.displayState = displayState;
|
||||||
}
|
}
|
||||||
@ -35,11 +35,11 @@ public class CalculatorHistoryState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public EditorHistoryState getDisplayState() {
|
public CalculatorDisplayHistoryState getDisplayState() {
|
||||||
return displayState;
|
return displayState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDisplayState(@NotNull EditorHistoryState displayState) {
|
public void setDisplayState(@NotNull CalculatorDisplayHistoryState displayState) {
|
||||||
this.displayState = displayState;
|
this.displayState = displayState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
|
|
||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
import bsh.EvalError;
|
import bsh.EvalError;
|
||||||
import bsh.Interpreter;
|
import bsh.Interpreter;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.solovyev.common.exceptions.SersoException;
|
import org.solovyev.common.exceptions.SersoException;
|
||||||
import org.solovyev.common.utils.MathUtils;
|
import org.solovyev.common.utils.MathUtils;
|
||||||
|
import org.solovyev.common.utils.StringUtils;
|
||||||
|
import org.solovyev.util.math.Complex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: serso
|
* User: serso
|
||||||
@ -32,22 +32,69 @@ public class CalculatorModel {
|
|||||||
interpreter.eval(Preprocessor.wrap(JsclOperation.importCommands, "/jscl/editorengine/commands"));
|
interpreter.eval(Preprocessor.wrap(JsclOperation.importCommands, "/jscl/editorengine/commands"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String evaluate(@NotNull JsclOperation operation, @NotNull String expression ) throws EvalError, ParseException {
|
public String evaluate(@NotNull JsclOperation operation, @NotNull String expression) throws EvalError, ParseException {
|
||||||
|
|
||||||
final String preprocessedExpression = Preprocessor.process(expression);
|
final String preprocessedExpression = Preprocessor.process(expression);
|
||||||
|
|
||||||
Log.d(CalculatorModel.class.getName(), "Preprocessed expression: " + preprocessedExpression);
|
//Log.d(CalculatorModel.class.getName(), "Preprocessed expression: " + preprocessedExpression);
|
||||||
|
|
||||||
Object evaluationObject = interpreter.eval(Preprocessor.wrap(operation, preprocessedExpression));
|
Object evaluationObject = interpreter.eval(Preprocessor.wrap(operation, preprocessedExpression));
|
||||||
String result = String.valueOf(evaluationObject).trim();
|
String result = String.valueOf(evaluationObject).trim();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Double dResult = Double.valueOf(result);
|
result = round(result);
|
||||||
result = String.valueOf(MathUtils.round(dResult, NUMBER_OF_FRACTION_DIGITS));
|
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
|
if (result.contains("sqrt(-1)")) {
|
||||||
|
try {
|
||||||
|
result = createResultForComplexNumber(result.replace("sqrt(-1)", "i"));
|
||||||
|
} catch (NumberFormatException e1) {
|
||||||
|
// throw original one
|
||||||
throw new ParseException(e);
|
throw new ParseException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new ParseException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String createResultForComplexNumber(@NotNull final String s) {
|
||||||
|
final Complex complex = new Complex();
|
||||||
|
|
||||||
|
String result = "";
|
||||||
|
// may be it's just complex number
|
||||||
|
int plusIndex = s.lastIndexOf("+");
|
||||||
|
if (plusIndex >= 0) {
|
||||||
|
complex.setReal(round(s.substring(0, plusIndex)));
|
||||||
|
result += complex.getReal();
|
||||||
|
result += "+";
|
||||||
|
} else {
|
||||||
|
plusIndex = s.lastIndexOf("-");
|
||||||
|
if (plusIndex >= 0) {
|
||||||
|
complex.setReal(round(s.substring(0, plusIndex)));
|
||||||
|
result += complex.getReal();
|
||||||
|
result += "-";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int multiplyIndex = s.indexOf("*");
|
||||||
|
if (multiplyIndex >= 0) {
|
||||||
|
complex.setImag(round(s.substring(plusIndex >= 0 ? plusIndex+1 : 0, multiplyIndex)));
|
||||||
|
result += complex.getImag();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
result += "i";
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String round(@NotNull String result) {
|
||||||
|
final Double dResult = Double.valueOf(result);
|
||||||
|
result = String.valueOf(MathUtils.round(dResult, NUMBER_OF_FRACTION_DIGITS));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,4 +103,5 @@ public class CalculatorModel {
|
|||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.solovyev.android.view.CursorControl;
|
import org.solovyev.android.view.CursorControl;
|
||||||
import org.solovyev.android.view.HistoryControl;
|
import org.solovyev.android.view.HistoryControl;
|
||||||
import org.solovyev.common.math.calculators.Calculator;
|
|
||||||
import org.solovyev.common.utils.MutableObject;
|
import org.solovyev.common.utils.MutableObject;
|
||||||
import org.solovyev.common.utils.StringUtils;
|
import org.solovyev.common.utils.StringUtils;
|
||||||
import org.solovyev.common.utils.history.HistoryAction;
|
import org.solovyev.common.utils.history.HistoryAction;
|
||||||
@ -37,13 +36,13 @@ import org.solovyev.util.math.MathEntityType;
|
|||||||
public class CalculatorView implements CursorControl, HistoryControl<CalculatorHistoryState> {
|
public class CalculatorView implements CursorControl, HistoryControl<CalculatorHistoryState> {
|
||||||
|
|
||||||
// millis to wait before evaluation after user edit action
|
// millis to wait before evaluation after user edit action
|
||||||
public static final int EVAL_DELAY_MILLIS = 1000;
|
public static final int EVAL_DELAY_MILLIS = 500;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final CalculatorEditText editor;
|
private final CalculatorEditText editor;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final TextView display;
|
private final CalculatorDisplay display;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Activity activity;
|
private final Activity activity;
|
||||||
@ -52,7 +51,7 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
|||||||
private final CalculatorModel calculatorModel;
|
private final CalculatorModel calculatorModel;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private HistoryHelper<CalculatorHistoryState> history;
|
private final HistoryHelper<CalculatorHistoryState> history;
|
||||||
|
|
||||||
public CalculatorView(@NotNull final Activity activity, @NotNull CalculatorModel calculator) {
|
public CalculatorView(@NotNull final Activity activity, @NotNull CalculatorModel calculator) {
|
||||||
this.activity = activity;
|
this.activity = activity;
|
||||||
@ -64,10 +63,11 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
|||||||
this.editor.setInputType(InputType.TYPE_NULL);
|
this.editor.setInputType(InputType.TYPE_NULL);
|
||||||
imm.hideSoftInputFromWindow(this.editor.getWindowToken(), 0);
|
imm.hideSoftInputFromWindow(this.editor.getWindowToken(), 0);
|
||||||
|
|
||||||
this.display = (TextView) activity.findViewById(R.id.resultEditText);
|
this.display = (CalculatorDisplay) activity.findViewById(R.id.resultEditText);
|
||||||
this.display.setOnClickListener(new View.OnClickListener() {
|
this.display.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
if (((CalculatorDisplay) v).isValid()) {
|
||||||
final CharSequence text = ((TextView) v).getText();
|
final CharSequence text = ((TextView) v).getText();
|
||||||
if (!StringUtils.isEmpty(text)) {
|
if (!StringUtils.isEmpty(text)) {
|
||||||
final ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Activity.CLIPBOARD_SERVICE);
|
final ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Activity.CLIPBOARD_SERVICE);
|
||||||
@ -75,6 +75,7 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
|||||||
Toast.makeText(activity, "Result copied to clipboard!", Toast.LENGTH_SHORT).show();
|
Toast.makeText(activity, "Result copied to clipboard!", Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.history = new SimpleHistoryHelper<CalculatorHistoryState>();
|
this.history = new SimpleHistoryHelper<CalculatorHistoryState>();
|
||||||
@ -120,11 +121,14 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
|||||||
currentRunner.setObject(new Runnable() {
|
currentRunner.setObject(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
// allow only one runner at one time
|
||||||
synchronized (currentRunner) {
|
synchronized (currentRunner) {
|
||||||
|
//lock all operations with history
|
||||||
|
synchronized (history) {
|
||||||
// do only if nothing was post delayed before current instance was posted
|
// do only if nothing was post delayed before current instance was posted
|
||||||
if (currentRunner.getObject() == this) {
|
if (currentRunner.getObject() == this) {
|
||||||
// actually nothing shall be logged while text operations are done
|
// actually nothing shall be logged while text operations are done
|
||||||
evaluate(editorStateAfter, true);
|
evaluate(editorStateAfter);
|
||||||
|
|
||||||
if (history.isUndoAvailable()) {
|
if (history.isUndoAvailable()) {
|
||||||
history.undo(getCurrentHistoryState());
|
history.undo(getCurrentHistoryState());
|
||||||
@ -134,6 +138,7 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
new Handler().postDelayed(currentRunner.getObject(), EVAL_DELAY_MILLIS);
|
new Handler().postDelayed(currentRunner.getObject(), EVAL_DELAY_MILLIS);
|
||||||
@ -142,29 +147,26 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void evaluate(@Nullable final String expression, final boolean showError) {
|
private void evaluate(@Nullable final String expression) {
|
||||||
if (!StringUtils.isEmpty(expression)) {
|
if (!StringUtils.isEmpty(expression)) {
|
||||||
|
|
||||||
final TextView localDisplay = display;
|
final CalculatorDisplay localDisplay = display;
|
||||||
final Activity localActivity = activity;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Log.d(CalculatorView.class.getName(), "Trying to evaluate: " + expression);
|
Log.d(CalculatorView.class.getName(), "Trying to evaluate: " + expression);
|
||||||
localDisplay.setText(calculatorModel.evaluate(JsclOperation.numeric, expression));
|
localDisplay.setText(calculatorModel.evaluate(JsclOperation.numeric, expression));
|
||||||
} catch (EvalError e) {
|
} catch (EvalError e) {
|
||||||
handleEvaluationException(expression, showError, localDisplay, localActivity, e);
|
handleEvaluationException(expression, localDisplay, e);
|
||||||
} catch (CalculatorModel.ParseException e) {
|
} catch (CalculatorModel.ParseException e) {
|
||||||
handleEvaluationException(expression, showError, localDisplay, localActivity, e);
|
handleEvaluationException(expression, localDisplay, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleEvaluationException(@NotNull String expression, boolean showError, @NotNull TextView localDisplay, @NotNull Activity localActivity, @NotNull Exception e) {
|
private void handleEvaluationException(@NotNull String expression, @NotNull CalculatorDisplay localDisplay, @NotNull Exception e) {
|
||||||
Log.d(CalculatorView.class.getName(), "Evaluation failed for : " + expression + ". Error message: " + e.getMessage());
|
Log.d(CalculatorView.class.getName(), "Evaluation failed for : " + expression + ". Error message: " + e.getMessage());
|
||||||
localDisplay.setText("");
|
localDisplay.setText(R.string.c_syntax_error);
|
||||||
if (showError) {
|
localDisplay.setValid(false);
|
||||||
Toast.makeText(localActivity, R.string.syntax_error, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
@ -176,7 +178,7 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void evaluate() {
|
public void evaluate() {
|
||||||
evaluate(editor.getText().toString(), true);
|
evaluate(editor.getText().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processDigitButtonAction(@Nullable final String text) {
|
public void processDigitButtonAction(@Nullable final String text) {
|
||||||
@ -223,6 +225,7 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doHistoryAction(@NotNull HistoryAction historyAction) {
|
public void doHistoryAction(@NotNull HistoryAction historyAction) {
|
||||||
|
synchronized (history) {
|
||||||
if (history.isActionAvailable(historyAction)) {
|
if (history.isActionAvailable(historyAction)) {
|
||||||
final CalculatorHistoryState newState = history.doAction(historyAction, getCurrentHistoryState());
|
final CalculatorHistoryState newState = history.doAction(historyAction, getCurrentHistoryState());
|
||||||
if (newState != null) {
|
if (newState != null) {
|
||||||
@ -230,12 +233,20 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
|
public void setCurrentHistoryState(@NotNull CalculatorHistoryState editorHistoryState) {
|
||||||
|
synchronized (history) {
|
||||||
setValuesFromHistory(this.editor, editorHistoryState.getEditorState());
|
setValuesFromHistory(this.editor, editorHistoryState.getEditorState());
|
||||||
setValuesFromHistory(this.display, editorHistoryState.getDisplayState());
|
setValuesFromHistory(this.display, editorHistoryState.getDisplayState());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setValuesFromHistory(@NotNull CalculatorDisplay display, CalculatorDisplayHistoryState editorHistoryState) {
|
||||||
|
setValuesFromHistory(display, (EditorHistoryState)editorHistoryState);
|
||||||
|
display.setValid(editorHistoryState.isValid());
|
||||||
|
}
|
||||||
|
|
||||||
private void setValuesFromHistory(@NotNull TextView editText, EditorHistoryState editorHistoryState) {
|
private void setValuesFromHistory(@NotNull TextView editText, EditorHistoryState editorHistoryState) {
|
||||||
editText.setText(editorHistoryState.getText());
|
editText.setText(editorHistoryState.getText());
|
||||||
@ -247,7 +258,9 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
|||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public CalculatorHistoryState getCurrentHistoryState() {
|
public CalculatorHistoryState getCurrentHistoryState() {
|
||||||
return new CalculatorHistoryState(getEditorHistoryState(this.editor), getEditorHistoryState(this.display));
|
synchronized (history) {
|
||||||
|
return new CalculatorHistoryState(getEditorHistoryState(this.editor), getCalculatorDisplayHistoryState(this.display));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private EditorHistoryState getEditorHistoryState(@NotNull TextView textView) {
|
private EditorHistoryState getEditorHistoryState(@NotNull TextView textView) {
|
||||||
@ -258,4 +271,14 @@ public class CalculatorView implements CursorControl, HistoryControl<CalculatorH
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CalculatorDisplayHistoryState getCalculatorDisplayHistoryState(@NotNull CalculatorDisplay display) {
|
||||||
|
final CalculatorDisplayHistoryState result = new CalculatorDisplayHistoryState();
|
||||||
|
|
||||||
|
result.setText(String.valueOf(display.getText()));
|
||||||
|
result.setCursorPosition(display.getSelectionStart());
|
||||||
|
result.setValid(display.isValid());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
package org.solovyev.android.calculator;
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.solovyev.common.utils.CollectionsUtils;
|
||||||
|
import org.solovyev.common.utils.EqualsFinder;
|
||||||
|
import org.solovyev.common.utils.Finder;
|
||||||
|
import org.solovyev.util.math.Functions;
|
||||||
import org.solovyev.util.math.MathEntityType;
|
import org.solovyev.util.math.MathEntityType;
|
||||||
|
|
||||||
public class Preprocessor {
|
public class Preprocessor {
|
||||||
@ -14,49 +19,75 @@ public class Preprocessor {
|
|||||||
public static String process(@NotNull String s) {
|
public static String process(@NotNull String s) {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
final StartWithFinder startsWithFinder = new StartWithFinder(s);
|
||||||
for (int i = 0; i < s.length(); i++) {
|
for (int i = 0; i < s.length(); i++) {
|
||||||
char ch = s.charAt(i);
|
char ch = s.charAt(i);
|
||||||
|
|
||||||
checkMultiplicationSignBeforeFunction(sb, s, i);
|
checkMultiplicationSignBeforeFunction(sb, s, i);
|
||||||
|
|
||||||
if (ch == '[' || ch == '{') {
|
if (MathEntityType.openGroupSymbols.contains(ch)) {
|
||||||
sb.append('(');
|
sb.append('(');
|
||||||
} else if (ch == ']' || ch == '}') {
|
} else if (MathEntityType.closeGroupSymbols.contains(ch)) {
|
||||||
sb.append(')');
|
sb.append(')');
|
||||||
} else if (ch == 'π') {
|
} else if (ch == 'π') {
|
||||||
sb.append("pi");
|
sb.append("pi");
|
||||||
} else if (ch == '×' || ch == '∙') {
|
} else if (ch == '×' || ch == '∙') {
|
||||||
sb.append("*");
|
sb.append("*");
|
||||||
} else if (s.startsWith("ln", i)) {
|
} else {
|
||||||
sb.append("log");
|
startsWithFinder.setI(i);
|
||||||
i += 1;
|
final String function = CollectionsUtils.get(MathEntityType.functions, startsWithFinder);
|
||||||
} else if (s.startsWith("tg", i)) {
|
if (function != null) {
|
||||||
sb.append("tan");
|
sb.append(toJsclFunction(function));
|
||||||
i += 1;
|
i += function.length() - 1;
|
||||||
} else if (s.startsWith("atg", i)) {
|
|
||||||
sb.append("atan");
|
|
||||||
i += 2;
|
|
||||||
} else if (s.startsWith("acos", i)) {
|
|
||||||
sb.append("acos");
|
|
||||||
i += 3;
|
|
||||||
} else if (s.startsWith("asin", i)) {
|
|
||||||
sb.append("asin");
|
|
||||||
i += 3;
|
|
||||||
} else if (s.startsWith("e(", i)) {
|
|
||||||
sb.append("exp(");
|
|
||||||
i += 1;
|
|
||||||
} else if (ch == 'e') {
|
} else if (ch == 'e') {
|
||||||
sb.append("exp(1)");
|
sb.append("exp(1)");
|
||||||
} else if (ch == '√') {
|
} else if (ch == 'i') {
|
||||||
sb.append("sqrt");
|
sb.append("sqrt(-1)");
|
||||||
} else {
|
} else {
|
||||||
sb.append(ch);
|
sb.append(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static String toJsclFunction(@NotNull String function) {
|
||||||
|
final String result;
|
||||||
|
|
||||||
|
if (function.equals(Functions.LN)) {
|
||||||
|
result = Functions.LOG;
|
||||||
|
} else if (function.equals(Functions.SQRT_SIGN)) {
|
||||||
|
result = Functions.SQRT;
|
||||||
|
} else {
|
||||||
|
result = function;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class StartWithFinder implements Finder<String> {
|
||||||
|
|
||||||
|
private int i;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private final String targetString;
|
||||||
|
|
||||||
|
private StartWithFinder(@NotNull String targetString) {
|
||||||
|
this.targetString = targetString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFound(@Nullable String s) {
|
||||||
|
return targetString.startsWith(s, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setI(int i) {
|
||||||
|
this.i = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void checkMultiplicationSignBeforeFunction(@NotNull StringBuilder sb, @NotNull String s, int i) {
|
private static void checkMultiplicationSignBeforeFunction(@NotNull StringBuilder sb, @NotNull String s, int i) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
// get character before function
|
// get character before function
|
||||||
|
37
src/main/java/org/solovyev/util/math/Complex.java
Normal file
37
src/main/java/org/solovyev/util/math/Complex.java
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||||
|
* For more information, please, contact se.solovyev@gmail.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.solovyev.util.math;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: serso
|
||||||
|
* Date: 9/17/11
|
||||||
|
* Time: 11:35 PM
|
||||||
|
*/
|
||||||
|
public class Complex {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private String real, imag;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getReal() {
|
||||||
|
return real;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReal(@Nullable String real) {
|
||||||
|
this.real = real;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getImag() {
|
||||||
|
return imag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImag(@Nullable String imag) {
|
||||||
|
this.imag = imag;
|
||||||
|
}
|
||||||
|
}
|
40
src/main/java/org/solovyev/util/math/Functions.java
Normal file
40
src/main/java/org/solovyev/util/math/Functions.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||||
|
* For more information, please, contact se.solovyev@gmail.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.solovyev.util.math;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: serso
|
||||||
|
* Date: 9/17/11
|
||||||
|
* Time: 10:01 PM
|
||||||
|
*/
|
||||||
|
public interface Functions {
|
||||||
|
|
||||||
|
String SIN = "sin";
|
||||||
|
String SINH = "sinh";
|
||||||
|
String ASIN = "asin";
|
||||||
|
String ASINH = "asinh";
|
||||||
|
String COS = "cos";
|
||||||
|
String COSH = "cosh";
|
||||||
|
String ACOS = "acos";
|
||||||
|
String ACOSH = "acosh";
|
||||||
|
String TAN = "tan";
|
||||||
|
String TANH = "tanh";
|
||||||
|
String ATAN = "atan";
|
||||||
|
String ATANH = "atanh";
|
||||||
|
String LOG = "log";
|
||||||
|
String LN = "ln";
|
||||||
|
String MOD = "mod";
|
||||||
|
String EXP = "exp";
|
||||||
|
String SQRT_SIGN = "√";
|
||||||
|
String SQRT = "sqrt";
|
||||||
|
|
||||||
|
public static final List<String> all = Arrays.asList(SIN, SINH, ASIN, ASINH, COS, COSH, ACOS, ACOSH, TAN, TANH, ATAN, ATANH, LOG, LN, MOD, SQRT, SQRT_SIGN, EXP);
|
||||||
|
}
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
|
||||||
* For more information, please, contact se.solovyev@gmail.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.solovyev.util.math;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public enum MathEntity {
|
|
||||||
|
|
||||||
minus("-"),
|
|
||||||
equals("="),
|
|
||||||
factorial("!"),
|
|
||||||
plus("+"),
|
|
||||||
multiply("*"),
|
|
||||||
divide("/"),
|
|
||||||
power("^"),
|
|
||||||
sin("sin"),
|
|
||||||
asin("asin"),
|
|
||||||
cos("cos"),
|
|
||||||
acos("acos"),
|
|
||||||
tg("tg"),
|
|
||||||
atg("atg"),
|
|
||||||
exp("exp"),
|
|
||||||
log("log"),
|
|
||||||
ln("ln"),
|
|
||||||
mod("mod"),
|
|
||||||
sqrt("sqrt");
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private final String text;
|
|
||||||
|
|
||||||
private MathEntity (@NotNull String text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public String getText() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
@ -24,7 +24,7 @@ public enum MathEntityType {
|
|||||||
group_symbols,
|
group_symbols,
|
||||||
group_symbol;
|
group_symbol;
|
||||||
|
|
||||||
public static final List<Character> constants = Arrays.asList('e', 'π');
|
public static final List<Character> constants = Arrays.asList('e', 'π', 'i');
|
||||||
|
|
||||||
public static final List<Character> dots = Arrays.asList('.', ',');
|
public static final List<Character> dots = Arrays.asList('.', ',');
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ public enum MathEntityType {
|
|||||||
|
|
||||||
public static final List<Character> binaryOperations = Arrays.asList('-', '+', '*', '×', '∙', '/', '^' );
|
public static final List<Character> binaryOperations = Arrays.asList('-', '+', '*', '×', '∙', '/', '^' );
|
||||||
|
|
||||||
public static final List<String> functions = Arrays.asList("sin", "asin", "cos", "acos", "tg", "atg", "log", "ln", "mod", "√");
|
public static final List<String> functions = Functions.all;
|
||||||
|
|
||||||
public static final List<String> groupSymbols = Arrays.asList("[]", "()", "{}");
|
public static final List<String> groupSymbols = Arrays.asList("[]", "()", "{}");
|
||||||
|
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2011. Created by serso aka se.solovyev.
|
||||||
|
* For more information, please, contact se.solovyev@gmail.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.solovyev.android.calculator;
|
||||||
|
|
||||||
|
import de.congrace.exp4j.Calculable;
|
||||||
|
import de.congrace.exp4j.ExpressionBuilder;
|
||||||
|
import de.congrace.exp4j.UnknownFunctionException;
|
||||||
|
import de.congrace.exp4j.UnparsableExpressionException;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: serso
|
||||||
|
* Date: 9/17/11
|
||||||
|
* Time: 9:47 PM
|
||||||
|
*/
|
||||||
|
public class CalculatorModelTest {
|
||||||
|
@Test
|
||||||
|
public void testEvaluate() throws Exception {
|
||||||
|
final CalculatorModel cm = new CalculatorModel();
|
||||||
|
|
||||||
|
Assert.assertEquals("4.0", cm.evaluate(JsclOperation.numeric, "2+2"));
|
||||||
|
Assert.assertEquals("-0.7568", cm.evaluate(JsclOperation.numeric, "sin(4)"));
|
||||||
|
Assert.assertEquals("0.5236", cm.evaluate(JsclOperation.numeric, "asin(0.5)"));
|
||||||
|
Assert.assertEquals("-0.39626", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)"));
|
||||||
|
Assert.assertEquals("-0.5604", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)sqrt(2)"));
|
||||||
|
Assert.assertEquals("-0.5604", cm.evaluate(JsclOperation.numeric, "sin(4)asin(0.5)√(2)"));
|
||||||
|
Assert.assertEquals("7.38906", cm.evaluate(JsclOperation.numeric, "e^2"));
|
||||||
|
Assert.assertEquals("7.38906", cm.evaluate(JsclOperation.numeric, "exp(1)^2"));
|
||||||
|
Assert.assertEquals("7.38906", cm.evaluate(JsclOperation.numeric, "exp(2)"));
|
||||||
|
Assert.assertEquals("2.0+i", cm.evaluate(JsclOperation.numeric, "2*1+sqrt(-1)"));
|
||||||
|
Assert.assertEquals("0.92054+3.14159i", cm.evaluate(JsclOperation.numeric, "ln(5cosh(38π√(2cos(2))))"));
|
||||||
|
Assert.assertEquals("7.38906i", cm.evaluate(JsclOperation.numeric, "iexp(2)"));
|
||||||
|
Assert.assertEquals("2.0+7.38906i", cm.evaluate(JsclOperation.numeric, "2+iexp(2)"));
|
||||||
|
Assert.assertEquals("2.0+7.38906i", cm.evaluate(JsclOperation.numeric, "2+√(-1)exp(2)"));
|
||||||
|
Assert.assertEquals("2.0-2.5i", cm.evaluate(JsclOperation.numeric, "2-2.5i"));
|
||||||
|
Assert.assertEquals("-2.0-2.5i", cm.evaluate(JsclOperation.numeric, "-2-2.5i"));
|
||||||
|
Assert.assertEquals("-2.0+2.5i", cm.evaluate(JsclOperation.numeric, "-2+2.5i"));
|
||||||
|
Assert.assertEquals("-2.0+2.1i", cm.evaluate(JsclOperation.numeric, "-2+2.1i"));
|
||||||
|
Assert.assertEquals("-3.41007+3.41007i", cm.evaluate(JsclOperation.numeric, "(5tan(2i)+2i)/(1-i)"));
|
||||||
|
Assert.assertEquals("-0.1-0.2i", cm.evaluate(JsclOperation.numeric, "(1-i)/(2+6i)"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testComplexNumbers() throws Exception {
|
||||||
|
final CalculatorModel cm = new CalculatorModel();
|
||||||
|
|
||||||
|
Assert.assertEquals("1.22133+23123.0i", cm.createResultForComplexNumber("1.22133232+23123*i"));
|
||||||
|
Assert.assertEquals("1.22133+1.2i", cm.createResultForComplexNumber("1.22133232+1.2*i"));
|
||||||
|
Assert.assertEquals("1.22i", cm.createResultForComplexNumber("1.22*i"));
|
||||||
|
Assert.assertEquals("i", cm.createResultForComplexNumber("i"));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user