在 Java 里不建议用 float / double 表示金额,核心原因是:它们是“二进制浮点数”,不能精确表示很多十进制小数,而金额又要求绝对精确。
下面从原理到例子说明。
float 和 double 遵循 IEEE 754 标准,底层是二进制分数:
0.1(十进制) = 0.0001100110011...(二进制无限循环)
就像 1/3 在十进制里是 0.3333... 永远写不完一样,0.1 在二进制里也是无限循环的。
而 float / double 的位数是固定的(float 32 位,double 64 位),只能截断存储,于是就产生了误差。
System.out.println(0.1 + 0.2);
输出:
0.30000000000000004
如果用它算钱:
double money = 0.1;
money += 0.2;
System.out.println(money);
你以为是 0.3,实际是 0.30000000000000004
➡ 钱变“多”了一点点,但账目已经不对了
if (a + b == c) // 可能永远为 false
交易次数越多,误差越大:
double sum = 0.0;
for (int i = 0; i < 1000000; i++) {
sum += 0.1;
}
System.out.println(sum); // 不是 100000.0
0.1 * 3 == 0.3 // false
BigDecimal(最常用)BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
BigDecimal c = a.add(b); // 0.3
⚠ 注意:必须用字符串构造,不要:
new BigDecimal(0.1) // ❌ 仍然是浮点误差
long moneyInCents = 100; // 1.00 元
moneyInCents += 20; // 1.20 元
适合:
BIGINTDECIMAL(19,2)FLOAT / DOUBLE✅ 可以用在:
❌ 不适合:
float/double是“近似值”,金额需要“精确值”,所以不能用。
如果你愿意,我也可以给你一份支付系统中金额处理的规范示例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。