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

105 Views Asked by At

I am studying Matlab, and I do not understand why (eps * 0.5) + 1 is not greater than 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

I thought eps is the smallest number I can add to 1. So, adding 1 to a number less than eps does this problem?

1

There are 1 best solutions below

1
On

When addition is performed, or almost any floating-point operation generally, the correctly rounded result1 is as if:

  • We computed the exact result using real-number arithmetic.
  • That result were rounded to the nearest representable number (using whichever choice of rounding rule is in effect).

The most common rounding rule is to round to the nearest representable number and, in case of a tie, to round to the number with the even low digit.2

In the format commonly used for double precision, 1 is represented as:

+1.0000000000000000000000000000000000000000000000002•20

(I have marked the last digit in bold to mark its position visually). The next representable number is

+1.0000000000000000000000000000000000000000000000012•20

eps, the so-called “machine epsilon,” is:

+0.0000000000000000000000000000000000000000000000012•20

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

+1.00000000000000000000000000000000000000000000000012•20

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

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

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

If you add ⅝ eps 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.

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.