当我打印
时(new BigDecimal(5) * new BigDecimal(0.049))
它给出了
0.24500000000000000943689570931383059360086917877197265625
当我使用ROUND_HALF_EVEN
进行舍入时(new BigDecimal(5) * new BigDecimal(0.049)).setScale(2, BigDecimal.ROUND_HALF_EVEN)
打印
0.25
所以我的困惑是,它不应该是偶数,所以代替0.25不应该是0.24。请帮助解决这个困惑。谢谢!
答案 0 :(得分:8)
这里的真正问题是你使用了BigDecimal
的错误构造函数。
(new BigDecimal(5).multiply(new BigDecimal("0.049"))).setScale(2, BigDecimal.ROUND_HALF_EVEN)
会做你想要的。
问题是0.049
是浮点文字,并且该值不能完全表示为浮点值(float
和double
),引入了一个微小的错误,在这种情况下是有意义的。
通过使用接受String
参数的构造函数,您可以避免通过浮点转换并获得您想要的确切值。
由于精度有限,计算机上的浮点运算充满了令人讨厌的意外行为。如果您想了解有关陷阱的更多信息,请阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic
示例:
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);
}
打印
0.24
0.25
答案 1 :(得分:4)
int java.math.BigDecimal.ROUND_HALF_EVEN:6 [0x6]
舍入模式以绕过最近邻居"除非两个邻居都是等距的,在这种情况下,朝着偶数邻居转。
0.24500000000000000943689570931383059360086917877197265625
更接近0.25
而不是0.24
。只选择偶数邻居是两个邻居的距离相等(即如果你试图绕0.245
)。
BigDecimal bd = new BigDecimal("0.245").setScale(2, BigDecimal.ROUND_HALF_EVEN);
System.out.println (bd);
将打印0.24
。