为什么计算机科学中“(eps * 0.5) + 1”不大于“1”?

m61*_*615 0 math floating-point precision matlab epsilon

我正在学习Matlab,我不明白为什么(eps * 0.5) + 1不大于1。

eps

ans =

     2.220446049250313e-16

fprintf('%.52f\n', eps);
0.0000000000000002220446049250313080847263336181640625
sign(eps)

ans =

     1

% 1 means that eps is >= 0
eps >= 0

ans =

  logical

   1

eps > 0

ans =

  logical

   1

eps < 0

ans =

  logical

   0

% so, now I take half of eps
my_half_eps = eps * 0.5;
my_half_eps

my_half_eps =

     1.110223024625157e-16

fprintf('%.52f\n', my_half_eps);
0.0000000000000001110223024625156540423631668090820312
sign(my_half_eps)

ans =

     1

% half eps is positive
my_half_eps >= 0

ans =

  logical

   1

my_half_eps > 0

ans =

  logical

   1

my_half_eps < 0

ans =

  logical

   0

fprintf('%.52f\n', (eps + 1));
1.0000000000000002220446049250313080847263336181640625
% correct
fprintf('%.52f\n', (my_half_eps + 1));
1.0000000000000000000000000000000000000000000000000000
% WHAT ???
diary off
Run Code Online (Sandbox Code Playgroud)

我认为eps是我能加到 1 的最小数。那么,给小于的数加 1eps有这个问题吗?

Eri*_*hil 5

当执行加法或几乎任何浮点运算时,正确舍入的结果1如下所示:

\n
    \n
  • 我们使用实数算术计算出精确的结果。
  • \n
  • 该结果被舍入为最接近的可表示数字(使用有效的舍入规则选择)。
  • \n
\n

最常见的舍入规则是四舍五入到最接近的可表示数字,如果出现平局,则四舍五入到具有偶数低位的数字。2

\n

在常用的精度格式中double,1 表示为:

\n
+1.00000000000000000000000000000000000000000000000 0 2 \xe2\x80\xa22 0
\n

(我用粗体标记了最后一个数字,以直观地标记其位置)。下一个可表示的数字是

\n
+1.00000000000000000000000000000000000000000000000 1 2 \xe2\x80\xa22 0
\n

eps,所谓\xe2\x80\x9cmachine epsilon,\xe2\x80\x9d为:

\n
+0.00000000000000000000000000000000000000000000000 1 2 \xe2\x80\xa22 0
\n

eps所以 \xc2\xbd加 1的实数运算结果为:

\n
+1.00000000000000000000000000000000000000000000000 0 1 2 \xe2\x80\xa22 0
\n

查看 1、\xc2\xbd + 1 的实数结果eps以及下一个可表示的数字,我们可以看到 \xc2\xbd eps+ 1 恰好位于两个可表示的数字之间的中间:

\n
+1.00000000000000000000000000000000000000000000000 0 2 \xe2\x80\xa22 0 \n+1.000000000000000000000000000000000000000000000000 0 0 1 2 \xe2\x80\xa22 0 \n+1.00000000000000000000000000000000000000000000000 1 2 \xe2\x80\xa22 0
\n

因此,\xc2\xbd 加 1 的浮点运算eps将产生偶数低位的邻居,即 1.00000000000000000000000000000000000000000000000 0 2 \xe2\x80\xa22 0 = 1。

\n

如果将 \xe2\x85\x9d 添加eps到 1,结果将是下一个可表示的数字 1.00000000000000000000000000000000000000000000000 1 2 \xe2\x80\xa22 0,因为实数结果将通过中间点,因此舍入将是下一个数字。

\n

脚注

\n

1正弦和幂(幂)等困难运算通常是通过不正确的舍入来实现的。这仅适用于单个操作;多个操作的序列通常不会产生正确舍入的结果,除非专门设计和记录。

\n

2在严格限制的格式中,具有一位数精度,两个邻居都可能以奇数位结尾,如 9\xe2\x80\xa210 0和 1\xe2\x80\xa210 1。在这种情况下,使用幅度较大的数字。

\n