先看现象
涉及诸如float或者double这两种浮点型数据的处理时,偶尔总会有一些怪怪的现象,不知道大家注意过没,举几个常见的栗子:
典型现象(一):条件判断超预期
System.out.println( 1f == 0.9999999f ); // 打印:false
System.out.println( 1f == 0.99999999f ); // 打印:true 纳尼?
典型现象(二):数据转换超预期
float f = 1.1f;
double d = (double) f;
System.out.println(f); // 打印:1.1
System.out.println(d); // 打印:1.100000023841858 纳尼?
典型现象(三):基本运算超预期
System.out.println( 0.2 + 0.7 );
// 打印:0.8999999999999999 纳尼?
典型现象(四):数据自增超预期
float f1 = 8455263f;
for (int i = 0; i < 10; i++) {
System.out.println(f1);
f1++;
}
// 打印:8455263.0
// 打印:8455264.0
// 打印:8455265.0
// 打印:8455266.0
// 打印:8455267.0
// 打印:8455268.0
// 打印:8455269.0
// 打印:8455270.0
// 打印:8455271.0
// 打印:8455272.0
float f2 = 84552631f;
for (int i = 0; i < 10; i++) {
System.out.println(f2);
f2++;
}
// 打印:8.4552632E7 纳尼?不是 +1了吗?
// 打印:8.4552632E7 纳尼?不是 +1了吗?
// 打印:8.4552632E7 纳尼?不是 +1了吗?
// 打印:8.4552632E7 纳尼?不是 +1了吗?
// 打印:8.4552632E7 纳尼?不是 +1了吗?
// 打印:8.4552632E7 纳尼?不是 +1了吗?
// 打印:8.4552632E7 纳尼?不是 +1了吗?
// 打印:8.4552632E7 纳尼?不是 +1了吗?
// 打印:8.4552632E7 纳尼?不是 +1了吗?
// 打印:8.4552632E7 纳尼?不是 +1了吗?
看到没,这些简单场景下的使用情况都很难满足我们的需求,所以说用浮点数(包括double和float)处理问题有非常多隐晦的坑在等着咱们!
怪不得技术总监发狠话:谁要是敢在处理诸如 商品金额、订单交易、以及货币计算时用浮点型数据(double/float),直接让我们走人!

原因出在哪里?
我们就以第一个典型现象为例来分析一下:

浮点数(float和double)在处理商品金额时容易导致精度问题,造成计算错误。由于计算机底层基于二进制计算,浮点数的十进制表示在转换过程中会丢失精度。例如,比较0.1和0.2的底层二进制表示会发现它们并不相等,这违反直觉。为了解决精度问题,可以使用字符串或数组表示大数,或者利用Java的BigDecimal类进行高精度计算。直接用double构造BigDecimal会导致精度损失,建议使用Double.toString(double)转换为字符串或使用BigDecimal.valueOf(double)方法。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



