Machine Epsilon is not equal to $MachineEpsilon I try to wrap my head around machine precision calculations in Mathematica (11.2, Linux). I do not understand the following behavior: $MachineEpsilon
2.22045*10^-16

$MachinePrecision 15.9546 2^-46 // N 1.42109*10^-14 N[1 + 2^-46,$MachinePrecision] == 1
True


Why does this statement still evaluate to True? It is so far away from $MachineEpsilon that it should evaluate to False? Furthermore, why does the following yield a result which is exactly equal to a mantissa of just 46bit? I guess its the same answer and the same question as above. one = 1; eps = 1; SetPrecision[one, prec]; SetPrecision[eps, prec]; For[ SetPrecision[eps = one, MachinePrecision], SetPrecision[one + eps, MachinePrecision] != 1, SetPrecision[eps = eps/2, MachinePrecision] ] eps 1/70368744177664  What I try to understand is what rules Mathematica applies that lead to such results. My problem is that currently I have the impression that I can't rely on SetPrecision[] etc. • Note that there is Internal$EqualTolerance which controls the tolerance of Equal. Read more here: stackoverflow.com/a/6626748/590388 – Alexey Popkov Aug 14 '18 at 13:13
• Thanks Alexey, that is exactly the background working logic I looked for. – Robin Geyer Aug 14 '18 at 14:03

This is expected. From the documentation of Equal (==):

Approximate numbers with machine precision or higher are considered equal if they differ in at most their last seven binary digits (roughly their last two decimal digits).

(point 4 under Details)

You can use SameQ (===) (note the . after the 1 to make it a machine precision number):

N[1 + 2^-46, $MachinePrecision] === 1. (* False *) N[1 + 2^-52,$MachinePrecision] === 1.
(* True *)


You can also look into Internal$EqualTolerance as pointed out in the comments. See the linked post for more information. • Is there a reason for doing it that way? – Robin Geyer Aug 14 '18 at 14:03 • @RobinGeyer So 0.1 + 0.2 == 0.3 will return True. stackoverflow.com/a/7545025/6673902 – Chip Hurst Aug 14 '18 at 14:16 • In[60]:= {0.1 + 0.2 == 0.3, Block[{Internal`$EqualTolerance = 0}, 0.1 + 0.2 == 0.3]} Out[60]= {True, False} – Chip Hurst Aug 14 '18 at 14:18
• OK, thanks, that makes sense. However, 7 Guard-Bits seems a little excessive ;-) – Robin Geyer Aug 14 '18 at 14:37
• @RobinGeyer depends on your field. I mean the hard alternative would be to fully expose everyone to the full brutality of floating point numbers. – Searke Aug 14 '18 at 14:59