문제

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.

다른 팁

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top