## Machine Epsilon is not equal to $MachineEpsilon 4 1 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. Question was closed 2020-05-18T02:45:17.153 2 Note that there is Internal$EqualTolerance which controls the tolerance of Equal. Read more here: https://stackoverflow.com/a/6626748/590388

– 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

2

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 – 2018-08-14T14:03:55.627 2 @RobinGeyer So 0.1 + 0.2 == 0.3 will return True. https://stackoverflow.com/a/7545025/6673902 – Chip Hurst – 2018-08-14T14:16:30.237 In:= {0.1 + 0.2 == 0.3, Block[{Internal`$EqualTolerance = 0}, 0.1 + 0.2 == 0.3]}

Out= {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