Question

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
Était-ce utile?

La solution

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.

Autres conseils

The BigDecimal by default always tries to return the exact result of an operation.

leftVal.divide(rightVal, 2, RoundingMode.HALF_UP);

where 2 is precision and RoundingMode.HALF_UP is rounding mode

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top