双精度浮点数相减会导致错误结果

3

我正在尝试从double中获取小数部分,以下是我的代码:

double  decimalvalue = 23423.1234-23423.0;
0.12340000000040163

但是在减法之后,我期望 decimalvalue 的值为 0.1234,但实际上它的值是 0.12340000000040163。请帮助我理解这种行为,是否有任何解决方法。


1
实数有无限多个,但双精度浮点数只有64位。 - user7116
3
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html - Mysticial
2个回答

8

我建议您查看以下内容:

计算机科学家应该了解的浮点数算术知识

维基百科:IEEE 754

浮点数中可以指定有限数量的值,但在表示范围内存在无限数量的浮点数。

因此,某些浮点数不能在任何浮点/双精度样式的数据类型中准确表示。

处理您特定问题的典型方法是避免直接进行相等性比较,而是进行epsilon测试:查看预期值和计算值是否彼此相差一些小数(与被减数相比),称为 epsilon

与之间接相关的概念是机器epsilon的概念,值得完全理解。


1
Epsilon 应该适用于被比较数的数量级。 - user7116
对于初学者来说,“Nearly equal”比==要糟糕得多。学习浮点数的工作原理,不要试图用破坏传递性的技巧来隐藏它。 - Pete Becker

3
这是一个四舍五入误差。在十进制下,你不能完美地用一定数量的数字(比如15)来表示1/3。在二进制下,有更多的东西也无法被表示,0.1234正好是其中之一。精度取决于比例,但对于double类型,大约为15个小数位。如果您想了解更多关于浮点数的详细信息,请查看http://en.wikipedia.org/wiki/IEEE_floating_point
如果您正在尝试制作类似人类使用的计算器的十进制系统,并且需要确切的结果,则应使用BCD。

"...你无法用有限的精度来表示。" - user7116
哈哈,我正准备自己修改它 :P - CrazyCasta

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