【问题标题】:Why is BigDecimal not rounded as expected为什么 BigDecimal 没有按预期四舍五入
【发布时间】:2013-09-23 11:32:24
【问题描述】:

下面的代码将 1620 除以 100,得到的结果是 16.00,而不是预期值 16.20。

MathContext mc = new MathContext(2, RoundingMode.HALF_EVEN);

BigDecimal num = new BigDecimal("1620").setScale(2, RoundingMode.HALF_EVEN);
BigDecimal divider = new BigDecimal(100).setScale(2,RoundingMode.HALF_EVEN);

BigDecimal result = num.divide(divider, mc).setScale(2, RoundingMode.HALF_EVEN);

打印出上面我得到的值

号码:1620.00 分频器 100.00 结果:16.00

如果我将 MathContext 中的精度更改为 4,我会得到 16.20 的结果,但为什么呢? MathContext 中的精度是否为 2 不会导致 16.20?

【问题讨论】:

    标签: java rounding bigdecimal


    【解决方案1】:

    精度指定有效数字的总数,而不是点右侧的数字。

    检查此代码

    MathContext mContext = new MathContext(2);
    BigDecimal bd1 = new BigDecimal(1234, mContext);
    BigDecimal bd2 = new BigDecimal(10, mContext);
    System.out.println("Big " + bd1.divide(bd2).toPlainString()); // returns 120
    

    这是有道理的,因为小数点的位置只是一个比例问题12.341.234+E1123.4-E1 相同。

    【讨论】:

    • 谢谢,有效数字与点右侧的数字正是我出错的地方。
    【解决方案2】:
    BigDecimal num = new BigDecimal("1620").setScale(2, RoundingMode.HALF_EVEN);
    BigDecimal divider = new BigDecimal(100).setScale(2,RoundingMode.HALF_EVEN);
    
    BigDecimal result = num.divide(divider).setScale(2,RoundingMode.HALF_EVEN);
    

    在您的情况下,只需五分钟即可完成我的回答,您通过设置 MathContext ( JAVADOC ) MathContext(int precision,RoundingMode setRoundingMode) 将精度设置为 2。

    精度为 2,因此只有两位数。

    希望对你有帮助

    【讨论】:

    • 谢谢,我的困惑的根源是SJuan76确定的,即2指的是总有效位,而不是小数点后。
    【解决方案3】:

    它与总位数有关。使用 round() 而不是 setScale()。

    【讨论】:

      【解决方案4】:

      当您将 2 传递给 MathContext 的构造函数时,您显然是在限制为除法计算的一些间歇值。我不知道这是否是 API 的意图......我猜不是。似乎是一个错误。

      不过你有几个选择。

      1. 在 MathContext 的构造函数中将 2 更改为 4,一切正常。
      2. 从您的代码中删除 setScale 和 MathContext,简化它并使其更准确。如果您一直在设置比例,则可能会根据输入截断有效数字。将精度和舍入模式直接添加到除法运算中。

      代码示例:

       BigDecimal num = new BigDecimal("1620");
       BigDecimal divider = new BigDecimal(100);
       BigDecimal result = num.divide(divider, 2, RoundingMode.HALF_EVEN);
      

      这给了我 16.20。

      【讨论】:

      • 不,这不是错误!
      • 啊,看来你是对的。我对问题的描述是错误的,但我的代码示例是准确的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多