Understanding round half even?

前端 未结 2 604
耶瑟儿~
耶瑟儿~ 2021-01-22 18:26

When i print

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

It gives

0.24500000000000000943689570931383059360086917877197265625
<         


        
相关标签:
2条回答
  • 2021-01-22 19:08

    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
    
    0 讨论(0)
  • 2021-01-22 19:22

    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.

    0 讨论(0)
提交回复
热议问题