What happens when adding 1 to a number close to MachineEpsilon?
Some of the confusion in the question is caused by the way Mathematica displays machine-precision numbers. For example, Mathematica's "nice" default settings make it appear that there's no difference between 1.0
and 1.0 + $MachineEpsilon
.
1.0
1.0 + $MachineEpsilon
The displayed results are the same, that is, 1.
. However, we can use RealDigits
to show that 1.0 + $MachineEpsilon
is not the same as 1.0
at machine-precision (assuming MachinePrecision is $\frac{53 \log (2)}{\log (10)}$≈15.9546).
RealDigits[1.0, 2] (* binary digits *)
RealDigits[1.0 + $MachineEpsilon, 2]
The results are:
{{1, 0, <<50 zeros>>, 0}, 1} (* least-significant digit is 0 *)
{{1, 0, <<50 zeros>>, 1}, 1} (* least-significant digit is 1 *)
The least-significant binary digit shows that 1.0
and 1.0 + $MachineEpsilon
are in fact different, and demonstrates that MachineEpsilon is "the minimum positive machine-precision number which can be added to 1.0 to give a result distinguishable from 1.0."
The point is that we can't rely on Mathematica's "nice" display of machine-precision numbers. We need to look as closely as possible at the binary result.
Case #1, where x = 0.0000000000000001
Consider the result of adding 1 to 0.0000000000000001.
x = 0.0000000000000001;
RealDigits[x + 1, 2]}
The result is {{1, 0, <<50 zeroes>> 0}, 1}
, and notice the least-significant digit is 0.
Case #2, where x = 0.0000000000000002
x = 0.0000000000000002;
RealDigits[x + 1, 2]
This time, the result is {{1, 0, <<50 zeros>> 1}, 1}
. Compare to case #1, where the least-significant digit was 0. This shows how decimal-to-binary conversion and using a number twice as large as case #1 produces a different result, and that the result is MachineEpsilon larger.
The different least-significant binary digits are the reason why the case #2 result isn't zero, and it is in fact the same as MachineEpsilon.
The case where x = 0.0000000000000003 is the same as x = 0.0000000000000002.
x = 0.0000000000000003;
RealDigits[x + 1, 2]
Another way to look at these results is to use extended-precision numbers instead of machine-precision values. For example, using case #2:
x = 0.0000000000000002;
SetPrecision[x + 1, 22]
The result is 1.000000000000000222045
. Notice the the digits 222045 from the value of MachineEpsilon.
To summarize, Mathematica displays machine-precision numbers in a "nice" way that doesn't show the full precision of the result of a calculation. We need to use RealDigits
or use extended precision to see the results of adding 1 to numbers close to MachineEpsilon.
Is MachineEpsilon the same as on any computer using Mathematica?
The value of MachineEpsilon is determined by the internal representation of machine-precision floating-point numbers. The value of MachinePrecision is $\frac{53 \log (2)}{\log (10)}$≈15.9546, when a computer uses IEEE Standard 754-1985 double-precision, 64-bit floating-point numbers. The value 53 comes from the number of bits used to store the mantissa (52) plus an assumed, normalized 1 bit to the left of the binary mantissa.
$MachineEpsilon
in Windows-based and OS-X-based systems differed because the Windows-based systems used Intel processors and Apple used Motorola/IBM processors. Apple changed over to Intel in 2006. So now it would be hard to find a system running Mathematica that doesn't give2.220446049250313`*^-16
for$MachineEpsilon
because that is the value retuned by any system running an Intel Core i3, i5, or i7 processor(s). $\endgroup$Log[2, $MachineEpsilon]
evaluates to-52.
andRootApproximant[$MachineEpsilon] === 2^-52
evaluates toTrue
$\endgroup$