Understanding round half even?

梦想与她 提交于 2019-12-31 04:58:24

问题


When i print

(new BigDecimal(5) * new BigDecimal(0.049))​

It gives

0.24500000000000000943689570931383059360086917877197265625

When i round it using the ROUND_HALF_EVEN

(new BigDecimal(5) * new BigDecimal(0.049)).setScale(2, BigDecimal.ROUND_HALF_EVEN)​

It prints

0.25

So my confusion is, shouldn't it round to even number, so instead of 0.25 shouldn't it be 0.24. Please help with this confusion. Thanks!


回答1:


The REAL issue here is that you used the wrong constructor for the BigDecimal.

(new BigDecimal(5).multiply(new BigDecimal("0.049"))).setScale(2, BigDecimal.ROUND_HALF_EVEN)​

will do what you want.

The problem is that 0.049 is a floating point literal, and that value is not representable exactly as a floating point value (neither float nor double), introducing a miniscule error that in this case is meaningful.

By using the constructor that accepts a String argument you avoid the conversion through floating point and get the exact value you intended.

Floating point arithmetic on computers is fraught with nasty unexpected behaviors due to its limited precision. If you want to learn more about the pitfalls, read What Every Computer Scientist Should Know About Floating-Point Arithmetic

Example:

public static void main(String[] args) {
    BigDecimal result1 = (new BigDecimal(5).multiply(new BigDecimal("0.049"))).setScale(2, BigDecimal.ROUND_HALF_EVEN);
    BigDecimal result2 = (new BigDecimal(5).multiply(new BigDecimal(0.049))).setScale(2, BigDecimal.ROUND_HALF_EVEN);
    System.out.println(result1);
    System.out.println(result2);
}

Prints

0.24
0.25



回答2:


int java.math.BigDecimal.ROUND_HALF_EVEN : 6 [0x6]

Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor.

0.24500000000000000943689570931383059360086917877197265625 is closer to 0.25 than to 0.24. The even neighbour is only chosen is the distance from both neighbors is equal (i.e. if you were trying to round 0.245).

BigDecimal bd = new BigDecimal("0.245").setScale(2, BigDecimal.ROUND_HALF_EVEN);
System.out.println (bd);

will print 0.24.



来源:https://stackoverflow.com/questions/47506242/understanding-round-half-even

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!