在某些情况下,BigDecimal是否过度杀伤?

时间:2013-01-28 18:03:14

标签: java floating-point bigdecimal

我正在使用钱,所以我需要我的结果准确但我只需要2位小数(美分)的精度。 BigDecimal是否需要保证乘法/除法的结果是准确的?

5 个答案:

答案 0 :(得分:17)

BigDecimal是十进制小数运算的一种非常合适的类型,小数点后面有一个已知的位数。您可以使用整数类型并自己跟踪乘数,但这涉及到可以自动执行的代码工作。

除了管理小数点后的数字之外,BigDecimal还会根据需要扩展存储数字的数量 - 许多商业和政府财务计算涉及的金额太大而无法存储在int中。

我会考虑避免它,只要你需要存储大量金钱,并且内存不足。

答案 1 :(得分:8)

一个常见的选择是使用整数或长整数(美分值)进行所有计算,然后在需要显示时简单地添加两个小数位。

同样,有一个JODA Money库可以为您提供更全面的API计算资金。

答案 2 :(得分:2)

这取决于您的申请。使用该准确度的一个原因是防止在许多操作中累积的错误渗透并导致有价值信息的丢失。如果您正在创建一个临时应用程序和/或仅用于数据输入,那么BigDecimal很可能是过度杀伤。

答案 3 :(得分:1)

为Patricias回答+1,但我非常强烈建议任何人使用固定比特长度为的整数数据类型实现自己的类,因为有些人真的不知道你在做什么。 BigDecimal支持所有舍入和精度问题,而long / int有严重问题:

  • 未知数量的小数位数:贸易交易所/法律/商业的数量不尽相同 小数位数,所以你不知道你所选择的位数是否必须改变 将来调整。更糟糕的是:有些东西比如股票评估需要一些荒谬的小数位数。具有1000公吨煤的船舶例如 冰费4,12欧元,导致0,000412欧元/吨。

  • 未实现的操作:这意味着人们可能会使用浮点数 舍入/除法或其他算术运算,隐藏不精确性和导致 所有已知的浮点运算问题。

  • 溢出/下溢:达到最大金额后,添加金额会导致更改符号。 Long.MAX_VALUE切换到Long.MIN_VALUE。如果您正在执行像(a * b * c * d)/(e * f)这样的分数,这可能很容易发生,这些分数可能在很长的范围内完全有效,但是中间提名者或分母确实

答案 4 :(得分:0)

您可以使用Currency编写自己的long课程来保存金额。类方法将使用String设置并获取金额。

无论您使用long还是BigDecimal,分部都会受到关注。您必须根据具体情况确定您使用小数分数做什么。丢弃它们,围绕它们,或保存它们(除了你自己的帐户之外的其他地方)。