问题描述
(new BigDecimal(5)* new BigDecimal(0.049))
code>
它给出了
0.24500000000000000943689570931383059360086917877197265625
当我使用ROUND_HALF_EVEN
(new BigDecimal(5)* new BigDecimal(0.049))。setScale(2,BigDecimal.ROUND_HALF_EVEN)
它打印
0.25
所以我的困惑是,不应该是偶数,所以0.25不应该是0.24。请帮助解决这个问题。谢谢!
这里的REAL问题是,您对 BigDecimal $使用了错误的构造函数(BigDecimal(5)* new BigDecimal(0.049))。setScale(2,BigDecimal(5)* new BigDecimal(0.049))。setScale(2,BigDecimal .ROUND_HALF_EVEN)
可以做你想做的事。
问题在于 0.049
是浮点数字,并且该值不能完全表示为浮点数值(既不是 float
也不是 double
),引入了一个在这种情况下有意义的小错误。
通过使用接受 String
参数的构造函数,您可以避免通过浮点进行转换并获得确切的值打算。
计算机上的浮点算法由于其精度有限而充满了令人讨厌的意外行为。如果您想了解更多有关陷阱的信息,请阅读
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!
The REAL issue here is that you used the wrong constructor for the BigDecimal
.
(new BigDecimal(5) * 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
这篇关于甚至理解一半?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!