双精度计算产生奇数结果

4
我有两个以Double格式存储的数字,分别为1.4300和1.4350。当我做减法操作1.4350 - 1.4300时,它返回结果:0.0050000000000001155。为什么会在末尾加上1155,并且该如何解决这个问题才能返回0.005或0.0050? 我不确定四舍五入是否可行,因为我正在使用2位和4位小数。
3个回答

14

哦,我喜欢这些......这是由于双精度表示的不准确性引起的,浮点运算充满了这些问题。通常是由二进制中的循环数字(即基于2的浮点表示)引起的。例如,在十进制中,1/3 = 0.3333',在二进制中,1/10是一个循环数字,这意味着它不能被完美地表示。试试这个:1-0.1-0.1-0.1-0.1,你得不到0.6 :-)

为了解决这个问题,可以使用BigDecimal(首选)或通过先将其乘以像10000这样的数字,然后四舍五入,再除以原来的数来操作double(不太干净)。

好问题......过去曾经造成了巨大的问题。导弹超出目标、卫星发射后坠毁等等。在网上搜索一下,你会惊讶的!


1
你是认真考虑导弹和卫星的问题吗?还是在讽刺? - mohdajami
6
请翻译以下两个链接的内容:http://ima.umn.edu/~arnold/455.f96/disasters.html 和 http://www.theinquirer.net/inquirer/news/1047844/floating-point-bugs-explode(这是我能找到的两个链接...) - Jaco Van Niekerk

4

这是一些计算机对分数进行表示的常见陷阱,可以参考这个问题或者在谷歌搜索中查询浮点精度。


1
+1:如此常见,令人惊讶的是人们竟然不知道它。 - Peter Lawrey

2

对于非常精度的浮点数计算,Double类型不是正确的选择,如果您想要精确的结果,则必须使用BigDecimal。


在这种情况下不需要使用BigDecimal(它有许多问题)。在输出时适当地四舍五入就足够了。 - sleske
@sleske:BigDecimal有什么问题?我知道的唯一一个问题就是性能。 - bezmax
@Max:主要是性能(CPU开销,内存使用和GC的额外工作),以及非常笨拙的API(没有使用运算符的方法)。 - sleske
@Max:BigDecimal 有其合理的使用场景。我只是想指出,在这种简单的情况下,它并不是必需的,因此在我看来应该避免使用。 - sleske

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接