我有一个处理大量金钱价值的Java项目,该项目主要涉及:
我只需要一些货币价值的精确度,而不是所有货币价值。所以我可以这样做:
如果我对所有变量使用BigDecimal,我想知道是否会出现任何性能问题?如果我选择1,我可以节省执行时间吗? 哪种方式最好? (我使用的是java 6)
答案 0 :(得分:3)
请勿将double
用于货币Why not use Double or Float to represent currency?
使用Big Decimal比内置基元慢100倍,您不能将+
和-
,/
和*
与BigDecimal
一起使用,但必须使用等效的BigDecimal方法调用。
另一种方法是使用int
代替双倍计算美分或任何小数货币等值,然后在将输出格式化为用户时,执行适当的转换以按用户期望的方式显示值
如果您的值非常大,则可以使用long
代替int
答案 1 :(得分:2)
这是一种权衡。
使用BigDecimal
,您正在使用不可变对象。这意味着每个操作都会导致创建新对象,这肯定会对内存产生一些影响。多少 - 这取决于很多事情 - 执行环境,计算的数量和复杂程度等等。但是你得到的是精确度,这是与钱合作时最重要的事情。
使用double
,您可以使用原始值,但精度很差,根本不适合进行货币计算。
如果我不得不提出一个方法 - 我会说在处理钱时肯定会使用BigDecimal
。
您是否考虑过将部分计算逻辑移至数据库层?这可以在内存和性能方面为您节省很多,并且您仍然可以保持精确的要求。
答案 2 :(得分:2)
BigDecimal
和double
是非常不同的类型,目的各不相同。 Java可以从两者中受益,Java程序员应该适当地使用它们。
浮点基元基于二进制,具有空间和时间效率。它们可以并且通常以非常快的硬件实现。 double
应该用在关于终止小数部分没有什么特别之处的上下文中,并且所需要的只是一个非常接近于可能是分数,非理性,非常大或非常小的值的近似值。 double
有许多触发和类似函数的良好实现。有关示例,请参阅java.lang.Math
。
BigDecimal
可以精确地表示任何终止小数部分。在终止小数部分具有特殊状态的情况下,例如许多货币计算,这是非常非常好的。
除了终止小数部分的精确表示之外,它还可用于更接近于例如:比double
可能的三分之一。但是,您需要近似于double
耗材的近似值的情况非常罕见。最接近的double
到三分之一是0.333333333333333314829616256247390992939472198486328125,这对于大多数实际目的而言足够接近。尝试测量三分之一英寸和0.3333333333333333英寸之间的差异。
BigDecimal
仅在软件中受支持,不支持double
具有的数学函数,并且空间和时间效率更低。
如果您的工作要么功能正常,请使用double
。如果您需要终止小数部分的精确表示,请使用BigDecimal
。