6

I stumbled over the following weird behavior when comparing floating-point numbers close to 1.0:

qq = 1.0 + 60.0 $MachineEpsilon;

and then

qq > 1.0

yields False. However,

qq - 1

yields

1.33227*10^-14

which is far above $MachineEpsilon = 2.22045*10^-16 (the smallest number eps satisfying (1.0 + eps > 1.0)==True when using 8-byte floating point numbers). Changing the first command to

qq = 1.0 + 65.0 $MachineEpsilon;

Leads to the expected behavior of (qq > 1.0) == True.

I'm running Mathematica 10.4.0.0 under Windows on an Intel i5.

Ron

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
RonH
  • 281
  • 1
  • 9
  • SetPrecision[qq, MachinePrecision] > 1 – Feyre Dec 06 '16 at 11:54
  • @Feyre Still False. – corey979 Dec 06 '16 at 12:02
  • @corey979 Sorry, should be 16 or higher, MachinePrecision only works with a qq rationalized as qq = 1 + 60 $MachineEpsilon, something I did without thought, first idea with precision issues is always using rational numbers. – Feyre Dec 06 '16 at 12:06
  • 3
    This comes about because Equal is fuzzy and mutually exclusive trichotomy is enforced. – Daniel Lichtblau Dec 06 '16 at 14:47
  • 1
    I think this "feature" deserves at least a comment in the documentation of $MachineEpsilon. There's a good section in the Help text to Equal[] under "Possible Issues". – RonH Dec 06 '16 at 15:50

1 Answers1

5

As said in a comment:

This comes about because Equal is fuzzy and mutually exclusive trichotomy is enforced. – Daniel Lichtblau Dec 6 '16 at 14:47

Perhaps this question also deserves some suggestions for workarounds. The tolerance is relative, so comparing with 0 effectively compares with no tolerance.

qq - 1.0 > 0
(*  True  *)

The amount of tolerance is controlled by Internal`$EqualTolerance, which can be set to zero. (For a related Q&A, see Machine Epsilon).

Block[{Internal`$EqualTolerance = 0}, qq > 1.0]
(*  True  *)
Michael E2
  • 235,386
  • 17
  • 334
  • 747