【发布时间】:2015-07-28 20:54:40
【问题描述】:
这是减法
第一个数字
Decimal 3.0000002
Hexadecimal 0x4040001
Binary: Sign[0], Exponent[1000_0000], Mantissa[100_0000_0000_0000_0000_0001]
减去第二个数字:
Decimal 3.000000
Hexadecimal 0x4040000
Binary: Sign[0], Exponent[1000_0000], Mantissa[100_0000_0000_0000_0000_0000]
============================================
在这种情况下,指数已经相同,我们只需要减去尾数。我们知道在 IEEE754 中,尾数前面有一个隐藏位 1。因此,结果尾数应该是:
Mantissa_1[1100_0000_0000_0000_0000_0001] - Mantissa_2[1100_0000_0000_0000_0000_0000]
等于
Mantissa_Rst = [0000_0000_0000_0000_0000_0001]
但是这个数字没有归一化,因为第一个隐藏位不是 1。因此我们将 Mantissa_Rst 右移 23 次,同时指数减 23。
那么我们就有了结果值
Hexadecimal 0x4040000
Binary: Sign[0], Exponent[0110_1000], Mantissa[000_0000_0000_0000_0000_0000].
总共 32 位,不需要四舍五入。
注意在尾数区域,还有一个隐藏的1。
如果我的计算是正确的,那么将结果转换为十进制数是0.00000023841858,与实际结果0.0000002相比,我仍然认为这不是很精确。
所以问题是,我的计算错了吗?或者实际上这是一个真实的情况,并且一直在计算机中发生?
【问题讨论】:
-
十进制数
3.0000002不能以2为底精确表示,它将四舍五入到最接近的可表示数字。将其转换为双精度并输出更多数字,您就会明白我的意思了。 -
这在计算机上一直发生。如果你想看的话。尝试计算 (1/3 + 1/3 +1/3) ==1。这是因为它可以正好是 0.0000002,尾数为 23,指数为 8
-
如果您认为这很糟糕,请意识到这是良性取消。还有一个类似的问题,称为灾难性取消。
标签: c++ floating-point floating-accuracy floating-point-precision