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:



2^-46 // N

N[1 + 2^-46, $MachinePrecision] == 1

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];
 SetPrecision[eps = one, MachinePrecision],
 SetPrecision[one + eps, MachinePrecision] != 1,
SetPrecision[eps = eps/2, MachinePrecision]


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.

Robin Geyer

Posted 2018-08-14T12:56:39.523

Reputation: 43

Question was closed 2020-05-18T02:45:17.153


Note that there is Internal`$EqualTolerance which controls the tolerance of Equal. Read more here:

– Alexey Popkov – 2018-08-14T13:13:47.403

Thanks Alexey, that is exactly the background working logic I looked for. – Robin Geyer – 2018-08-14T14:03:20.137



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.

Lukas Lang

Posted 2018-08-14T12:56:39.523

Reputation: 17 767

Is there a reason for doing it that way? – Robin Geyer – 2018-08-14T14:03:55.627


@RobinGeyer So 0.1 + 0.2 == 0.3 will return True.

– Chip Hurst – 2018-08-14T14:16:30.237

In[60]:= {0.1 + 0.2 == 0.3, Block[{Internal`$EqualTolerance = 0}, 0.1 + 0.2 == 0.3]}

Out[60]= {True, False} – Chip Hurst – 2018-08-14T14:18:13.110

OK, thanks, that makes sense. However, 7 Guard-Bits seems a little excessive ;-) – Robin Geyer – 2018-08-14T14:37:25.197

3@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 – 2018-08-14T14:59:05.713