在我的程序中,我有一个25个双值0.04的数组 当我尝试在循环中对这些值求和时,我得到以下结果:
0.0 + 0.04 = 0.04
0.04 + 0.04 = 0.08
0.08 + 0.04 = 0.12
0.12 + 0.04 = 0.16
0.16 + 0.04 = 0.2
0.2 + 0.04 = 0.24000000000000002
0.24000000000000002 + 0.04 = 0.28
0.28 + 0.04 = 0.32
0.32 + 0.04 = 0.36
0.36 + 0.04 = 0.39999999999999997
0.39999999999999997 + 0.04 = 0.43999999999999995
0.43999999999999995 + 0.04 = 0.4799999999999999
0.4799999999999999 + 0.04 = 0.5199999999999999
0.5199999999999999 + 0.04 = 0.5599999999999999
0.5599999999999999 + 0.04 = 0.6
0.6 + 0.04 = 0.64
0.64 + 0.04 = 0.68
0.68 + 0.04 = 0.7200000000000001
0.7200000000000001 + 0.04 = 0.7600000000000001
0.7600000000000001 + 0.04 = 0.8000000000000002
0.8000000000000002 + 0.04 = 0.8400000000000002
0.8400000000000002 + 0.04 = 0.8800000000000002
0.8800000000000002 + 0.04 = 0.9200000000000003
0.9200000000000003 + 0.04 = 0.9600000000000003
为什么会发生这种情况?!
答案 0 :(得分:23)
编程语言中最常见的浮点值存储 - IEEE singles and doubles - 没有大多数小数部分的精确表示。
原因是它们以二进制浮点格式存储值,而不是十进制浮点格式。唯一可以精确表示的小数值是两个负幂之和。数字如:
等
你所看到的是,像0.96这样的数字的表示并不完全可以表示,因为它们不能表示为两个负幂的总和。因此,当以十进制小数打印出全精度时,它们将与原始值不匹配。
答案 1 :(得分:14)
答案 2 :(得分:5)
其他答案提到了原因,但没有提到如何避免它。
有几种解决方案:
答案 3 :(得分:1)
您可能希望查看java BigDecimal类作为浮点数和双精度数的替代方法。