在Matlab中解释1 - 3 *(4/3 - 1)= 2.2204e-16

时间:2013-03-12 03:20:18

标签: matlab floating-point floating-accuracy ieee-754 double-precision

我试图理解Matlab中的双精度数字。为什么这个1 - 3 *(4/3 - 1)不等于零?

3 个答案:

答案 0 :(得分:6)

实数4/3不能用双精度(或任何其他二进制浮点格式)表示,因为它不是二元有理数。因此,当您在MATLAB中计算4/3时,您得到的值是舍入到最接近的可表示的双精度数,这正是:

1.3333333333333332593184650249895639717578887939453125

从这个值中减去1是精确的(这是一个众所周知的FP误差分析定理,它可以精确地减去两个因子内的数字),因此4/3 - 1的结果是:< / p>

0.3333333333333332593184650249895639717578887939453125

将这个数字乘以3的结果恰好也是可以表示的:

0.9999999999999997779553950749686919152736663818359375

最后,从1.0中减去也是准确的(根据前面提到的定理):

0.0000000000000002220446049250313080847263336181640625

因此,计算中只有一个舍入误差源,因为4/3不能表示为double,并且计算的最终结果只是结束了初始错误。

答案 1 :(得分:1)

在科学计算器上运行 - log 2 (2.2204e-16) - 产生(差不多)-52。换句话说,Matlab在double中存储52位精度,另外5位用于指数(4 +符号),一位用于有效数的符号。这与IEEE 754实现一致:有效数字为53位(52 +符号),指数为5位。一切都很好!与往常一样,您应该测试两个浮点数是否足够接近,而不是它们是否完全相等。 Matlab中的一个恰当的例子如下:

if abs(x - y) < 1e-15
      % Some code to execute when x and y are approximately equal
else
      % Some other code
end

遵守IEEE 754的声明来自the wikipedia article

答案 2 :(得分:0)

问题始于4/3的计算。确切的答案既不能表示有限数量的十进制数字,也不能表示有限数量的比特。结果将存储为4/3+r,其中r是一个小的绝对值有符号数,表示4/3的实际值与最接近的IEEE 754 64位二进制浮点数之间的差值,为4/3,即舍入误差。

1/3+r中减去1个结果。乘以3获得1+3r。从1中减去-3r

最终结果是原始表示形式4/3中的舍入误差的-3倍。