在Java应用程序中使用money数据类型的最佳实践是什么?钱应该是双变量吗?四舍五入,货币等等。是特殊的库吗?在大多数流行的数据库中,ORM和SQL呢?据我了解,并非所有SQL引擎都是Money数据类型。在这种情况下,应该使用NUMERIC(15,2)
,DECIMAL(15,2)
还是REAL数据类型?
在Java应用程序中使用money数据类型的最佳实践是什么?
使用BigDecimal。使用任何原始will迟早都会导致精度问题。
关于大多数流行的数据库中的ORM和SQL呢。
休眠(可能还有其他所有)可以很好地处理BigDecimal。并转换为适当的数据库类型,通常为DECIMAL。
您应使用BigDecimal
表示货币值。
摘自Bloch,J.,《有效Java》,第二版,第48项:
float
和double
类型是特别不适用于货币计算,因为这是不可能的代表0.1(或其他任何值)十的负幂)作为float
或完全是double
。例如,假设您有$ 1.03而您花费42c。多少钱你离开了吗?
System.out.println(1.03 - .42);
打印出
0.6100000000000001
。解决此问题的正确方法是使用
BigDecimal
,int
或long
用于货币计算。
对于SQL,我使用NUMERIC(19,2)
。
在开发界,通常认为使用BigDecimal来赚钱是Java的最佳实践。这并不是说总是比使用双重恕我直言更好,但是我建议您从BigDecimal开始。
对于SQL,我建议对BigDecimal使用匹配类型NUMERIC或DECIMAL,对double使用匹配类型REAL。
值得注意的是,我曾经工作过的所有投资银行和交易公司都将钱舍入为两倍(使用C ++和Java)。相反,我从未见过使用BigDecimal,但我曾见过NUMERIC用于数据库。出于会计目的,请使用BigDecimal。
不使用BigDecimal由Double或Float创建,用于存储优先编号。
https://stackoverflow.com/a/54681006/4587961
现在有一些示例为什么。
double doubleValue = 35.7;
BigDecimal fromDouble = new BigDecimal(doubleValue);
BigDecimal fromString = new BigDecimal("35.7");
boolean decimalsEqual = fromDouble.equals(fromString);
System.out.println("From double: " + fromDouble + " " + fromString.stripTrailingZeros().toPlainString());
System.out.println("decimalsEqual: " + decimalsEqual");
打印
From double: 35.7000000000000028421709430404007434844970703125 35.7
decimalsEqual: false
另外,在mongo中将大十进制存储为双精度值时,我也遇到了麻烦。然后调用具有双参数的BigDecimal构造函数。从double创建一个大的十进制是违反实际做法的。
以上链接中的更多详细信息和示例!