I have this code to perform
private String evaluateResult(boolean requestedByUser) {
if ((!requestedByUser && mOperationStack.size() != 4)
|| (requestedByUser && mOperationStack.size() != 3))
return null;
String left = mOperationStack.get(0);
String operator = mOperationStack.get(1);
String right = mOperationStack.get(2);
String tmp = null;
if (!requestedByUser)
tmp = mOperationStack.get(3);
BigDecimal leftVal = new BigDecimal(left);
BigDecimal rightVal = new BigDecimal(right);
BigDecimal result = null;
if (operator.equals("/")) {
result = leftVal.divide(rightVal);
} else if (operator.equals("x")) {
result = leftVal.multiply(rightVal);
} else if (operator.equals("+")) {
result = leftVal.add(rightVal);
} else if (operator.equals("-")) {
result = leftVal.subtract(rightVal);
}
String resultStr = result+"";
if (resultStr == null)
return null;
mOperationStack.clear();
if (!requestedByUser) {
mOperationStack.add(resultStr);
mOperationStack.add(tmp);
}
return resultStr;
}
now if i calculate 12/3 output is 4 but if i try to calculate 12/5 app crashes. Whenever divisor is not a factor of dividend app crahses.After reading logcat it appears that it is becuse of non-terminating division. How can i avoid it. here is my logcat
03-09 22:33:14.876: W/dalvikvm(20200): threadid=1: thread exiting with uncaught exception (group=0x410819c0)
03-09 22:33:14.883: E/AndroidRuntime(20200): FATAL EXCEPTION: main
03-09 22:33:14.883: E/AndroidRuntime(20200): java.lang.IllegalStateException: Could not execute method of the activity
03-09 22:33:14.883: E/AndroidRuntime(20200): at android.view.View$1.onClick(View.java:3607)
03-09 22:33:14.883: E/AndroidRuntime(20200): at android.view.View.performClick(View.java:4212)
03-09 22:33:14.883: E/AndroidRuntime(20200): at android.view.View$PerformClick.run(View.java:17476)
03-09 22:33:14.883: E/AndroidRuntime(20200): at android.os.Handler.handleCallback(Handler.java:800)
03-09 22:33:14.883: E/AndroidRuntime(20200): at android.os.Handler.dispatchMessage(Handler.java:100)
03-09 22:33:14.883: E/AndroidRuntime(20200): at android.os.Looper.loop(Looper.java:194)
03-09 22:33:14.883: E/AndroidRuntime(20200): at android.app.ActivityThread.main(ActivityThread.java:5371)
03-09 22:33:14.883: E/AndroidRuntime(20200): at java.lang.reflect.Method.invokeNative(Native Method)
03-09 22:33:14.883: E/AndroidRuntime(20200): at java.lang.reflect.Method.invoke(Method.java:525)
03-09 22:33:14.883: E/AndroidRuntime(20200): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
03-09 22:33:14.883: E/AndroidRuntime(20200): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
03-09 22:33:14.883: E/AndroidRuntime(20200): at dalvik.system.NativeStart.main(Native Method)
03-09 22:33:14.883: E/AndroidRuntime(20200): Caused by: java.lang.reflect.InvocationTargetException
03-09 22:33:14.883: E/AndroidRuntime(20200): at java.lang.reflect.Method.invokeNative(Native Method)
03-09 22:33:14.883: E/AndroidRuntime(20200): at java.lang.reflect.Method.invoke(Method.java:525)
03-09 22:33:14.883: E/AndroidRuntime(20200): at android.view.View$1.onClick(View.java:3602)
03-09 22:33:14.883: E/AndroidRuntime(20200): ... 11 more
03-09 22:33:14.883: E/AndroidRuntime(20200): Caused by: java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result
03-09 22:33:14.883: E/AndroidRuntime(20200): at java.math.BigDecimal.divide(BigDecimal.java:1266)
03-09 22:33:14.883: E/AndroidRuntime(20200): at com.example.calculator.MainActivity.evaluateResult(MainActivity.java:239)
03-09 22:33:14.883: E/AndroidRuntime(20200): at com.example.calculator.MainActivity.ProcessInput(MainActivity.java:149)
03-09 22:33:14.883: E/AndroidRuntime(20200): ... 14 more
According to the documentation BigDecimal
will throw an ArithmeticException
when the result is a non-terminating decimal. You need to specify the rounding mode:
leftVal.divide(rightVal,BigDecimal.HALF_UP);
If you want to round it to more decimals you can use setScale(numDecimals)
before doing the division.