【问题标题】:Explain 1 - 3*(4/3 - 1) = 2.2204e-16 in Matlab在 Matlab 中解释 1 - 3*(4/3 - 1) = 2.2204e-16
【发布时间】:2013-03-12 03:20:18
【问题描述】:

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

【问题讨论】:

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


【解决方案1】:

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

1.3333333333333332593184650249895639717578887939453125

从这个值中减去 1 是精确的(众所周知的 FP 误差分析定理,即在一个因数为 2 内的数字相减是精确的),所以4/3 - 1 的结果是:

0.3333333333333332593184650249895639717578887939453125

碰巧这个数乘以三的结果也可以精确表示:

0.9999999999999997779553950749686919152736663818359375

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

0.0000000000000002220446049250313080847263336181640625

因此,您的计算中只有一个舍入误差源,因为 4/3 不能表示为双精度数,并且计算的最终结果只是初始误差结转。

【讨论】:

    【解决方案2】:

    在科学计算器上运行它 - log2(2.2204e-16) - 产生(几乎)正好 -52。换句话说,Matlab 将 52 位精度存储在 double 中,另外 5 位用于指数(4 + 符号),1 位用于有效数的符号。这与 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

    【讨论】:

    • 哇,一个模组看到了我的答案。这是第一次。
    • 另外,我通过包含“abs”功能编辑了上面的答案。非常重要!
    【解决方案3】:

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

    减去 1 得到1/3+r。乘以 3 得到1+3r。从 1 中减去它得到-3r

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

    【讨论】:

      猜你喜欢
      • 2015-04-07
      • 2017-10-21
      • 2021-07-04
      • 1970-01-01
      • 2021-04-19
      • 1970-01-01
      • 2021-01-09
      • 1970-01-01
      • 2016-11-27
      相关资源
      最近更新 更多