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

Why is "(eps * 0.5) + 1" not greater than "1" in computer science?

提问人:m615 提问时间:11/6/2023 最后编辑:Cris Luengom615 更新时间:11/7/2023 访问量:76

问:

我正在学习Matlab,我不明白为什么不大于1。(eps * 0.5) + 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

我认为这是我可以加到 1 的最小数字。那么,将 1 加到一个数字上比这个问题少吗?epseps

MATLAB 数学 浮点 精度 epsilon

评论

4赞 Brian61354270 11/6/2023
我不确定我是否理解这种困惑是什么。你似乎知道这是和下一个可表示的数字之间的距离。为什么添加小于的增量会返回相同的数字,这令人惊讶?eps1eps
0赞 Brian61354270 11/6/2023
你是在问为什么四舍五入而不是?11+eps
0赞 Cris Luengo 11/7/2023
或者您是否对操作数的顺序感到困惑? 与 相同。my_half_eps + 11 + my_half_eps
0赞 Severin Pappadeux 11/7/2023
eps 是 1 之后的下一个数字。从字面上看,1 和 1+eps 之间没有任何内容。你只是向自己证明了这一点
0赞 m615 11/7/2023
所以,例如:(eps-1) 不存在,所以这就像 0 ?

答:

5赞 Eric Postpischil 11/7/2023 #1

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

  • 我们使用实数算术计算了确切的结果。
  • 该结果四舍五入到最接近的可表示数字(使用有效的舍入规则选择)。

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

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

+1.0000000000000000000000000000000000000000000000002•20

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

+1.0000000000000000000000000000000000000000000000012•20

eps,所谓的“机器epsilon”,是:

+0.0000000000000000000000000000000000000000000000012•20

So the real-number arithmetic result of adding ½ to 1 is:eps

+1.00000000000000000000000000000000000000000000000012•20

Looking at 1, the real-number result of ½ + 1, and the next representable number, we can see ½ + 1 is exactly halfway between the two representable numbers:epseps

+1.0000000000000000000000000000000000000000000000002•20
+1.00000000000000000000000000000000000000000000000012•20
+1.0000000000000000000000000000000000000000000000012•20

Therefore, the floating-point operation of adding ½ to 1 will produce the neighbor with the even low digit, which is 1.0000000000000000000000000000000000000000000000002•20 = 1.eps

If you add ⅝ to 1, the result will be the next representable number, 1.0000000000000000000000000000000000000000000000012•20, because the real-number result will pass the halfway point, so the rounding will be to the next number.eps

Footnote

1 Difficult operations such as sine and power (exponentiation) are often implemented with less than correct rounding. And this applies to single operations only; sequences of multiple operations are generally not expected to produce a correctly rounded result, unless specifically designed and documented for that.

2 In a severely limited format, with one-digit precision, it is possible both neighbors end in odd digits, as with 9•100 and 1•101. In this case, the number with greater magnitude is used.

评论

0赞 chux - Reinstate Monica 11/7/2023
"both neighbors end in odd digits" --> interesting.