在处理现实世界的货币价值时,我建议使用BigDecimal而不是Double.But我没有一个令人信服的解释,除了“通常以这种方式完成”。
请注意这个问题吗?
答案 0 :(得分:38)
它被称为精度损失,并且在使用非常大的数字或非常小的数字时非常明显。具有基数的十进制数的二进制表示在许多情况下是近似值而不是绝对值。要理解为什么需要读取二进制中的浮点数表示。这是一个链接:http://en.wikipedia.org/wiki/IEEE_754-2008。这是一个快速演示:
在bc(任意精度计算器语言)中,精度= 10:
(1/3 + 1/12 + 1/8 + 1/30)= 0.6083333332
(1/3 + 1/12 + 1/8)= 0.541666666666666
(1/3 + 1/12)= 0.416666666666666
Java double:
0.6083333333333333
0.5416666666666666
0.41666666666666663
Java float:
0.60833335
0.5416667
0.4166667
如果您是银行并且每天负责数千笔交易,即使他们不是来自同一个帐户(或者可能是他们),您也必须拥有可靠的号码。二进制花车不可靠 - 除非您了解它们的工作原理和限制,否则不会这样。
答案 1 :(得分:32)
答案 2 :(得分:29)
虽然BigDecimal可以存储比double更高的精度,但通常不需要这样做。它使用的真正原因是因为它清楚地表明了如何执行舍入,包括许多不同的舍入策略。在大多数情况下,您可以使用double获得相同的结果,但除非您知道所需的技术,否则BigDecimal是这种情况下的方法。
一个常见的例子就是金钱。尽管在99%的使用情况下钱不会大到需要BigDecimal的精度,但使用BigDecimal通常被认为是最佳实践,因为在软件中控制舍入是避免了开发人员制造的风险处理四舍五入的错误。即使您有信心可以使用double
处理舍入,我建议您使用辅助方法来执行彻底测试的舍入。
答案 3 :(得分:1)
这主要是出于精确性的原因。 BigDecimal存储具有无限精度的浮点数。你可以看看这个解释得很好的页面。 http://blogs.oracle.com/CoreJavaTechTips/entry/the_need_for_bigdecimal
答案 4 :(得分:0)
当使用BigDecimal时,它可以存储更多的数据,然后是Double,这使得它更加准确,并且只是现实世界中更好的选择。
虽然速度慢很多,但值得。
打赌你不想给老板不准确的信息,是吗?答案 5 :(得分:0)
另一个想法:跟踪long
中的分数。这更简单,并且避免了繁琐的语法和BigDecimal
的缓慢性能。
财务计算的准确性非常重要,因为当资金因舍入错误而消失时,人们会非常愤怒,这就是为什么double
是处理资金的可怕选择。