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?
When addition is performed, or almost any floating-point operation generally, the correctly rounded result1 is as if:
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:(I have marked the last digit in bold to mark its position visually). The next representable number is
eps
, the so-called “machine epsilon,” is:So the real-number arithmetic result of adding ½
eps
to 1 is: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: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.