Understanding round half even?

前端 未结 2 605
耶瑟儿~
耶瑟儿~ 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
    

提交回复
热议问题