数学运算的意外结果

时间:2016-06-19 15:16:30

标签: java android bigdecimal

在执行数学运算以开发用于简单计算器的Android应用程序时,导致减法和除法运算的奇怪结果。其他操作与提供的输入相得益彰。在我的精确处理研究中,遇到了BigDecimal类,减少了我的错误。

某些操作(如减法和除法)未产生正确的结果。我在这里提供代码片段。

.
.
.
String answer = "";
BigDecimal bigDecimal1, bigDecimal2;
BigDecimal bigDecimalResult;
String operation = "";
.
.
.

                case R.id.button_substraction:
                    bigDecimal1 = new BigDecimal(answer);
                    operation = "-";
                    answer = "";
                    textViewAnswer.setText(buttonSubstraction.getText().toString());
                    break;
                case R.id.button_division:
                    bigDecimal1 = new BigDecimal(answer);
                    operation = "/";
                    answer = "";
                    textViewAnswer.setText(buttonDivision.getText().toString());
                    break;
                case R.id.button_equal:
                    bigDecimal2 = new BigDecimal(answer);
                    answer = "";
                    switch (operation) {
                           .
                           .

                        case "-":
                            bigDecimalResult = (bigDecimal1.subtract(bigDecimal2)).setScale(6,RoundingMode.HALF_UP).stripTrailingZeros();
                            textViewAnswer.setText(bigDecimalResult.toString());
                            break;

                        case "/":
                            bigDecimalResult = (bigDecimal1.divide(bigDecimal2)).setScale(6,RoundingMode.HALF_UP).stripTrailingZeros();
                            textViewAnswer.setText(bigDecimalResult.toString());
                            break;
                    }
.
.
.

示例:

  1. 减法
  2. 当从自身中减去一个数字时,结果为0,精度值为6(在代码中设置)为,

    100 - 100 = 0.000000

    即使指定了stripTrailingZeros()。

    1. 试图划分

      1/9

      崩溃了我的应用。

      • 逻辑实现出错了吗?
      • 当使用BigDecimal类时,是否与内存中的存储表示有关?

1 个答案:

答案 0 :(得分:1)

在Java 8中修复了stripTrailingZeros()没有剥离零值的问题 见JDK-6480539: BigDecimal.stripTrailingZeros() has no effect on zero itself ("0.0")

1 / 9导致您的应用崩溃的问题,原因在于您的逻辑:

bigDecimalResult = bigDecimal1.divide(bigDecimal2)
                              .setScale(6, RoundingMode.HALF_UP)
                              .stripTrailingZeros()

您尝试在划分后设置,但1 / 9没有确切的值,因此divide()方法会抛出异常,如javadoc中所述

  

如果确切的商没有终止十进制扩展

,则抛出ArithmeticException

您应该调用divide()方法的其他重载之一:

bigDecimalResult = bigDecimal1.divide(bigDecimal2, 6, RoundingMode.HALF_UP)
                              .stripTrailingZeros()

现在,请注意stripTrailingZeros()的结果。例如。如果结果为100.00000stripTrailingZeros()将逐字地删除所有零,从而产生1E+2。这可能不是你想要的。

要以更易读的方式打印,您可能需要使用toPlainString()代替toString()