# Different floating-point numbers equal?

Let's define two different numbers.

x = 1.
y = 1. + 2^-52 (* equivalently, 1 + MachineEpsilon *) Let's make sure they're different with FullForm: x // FullForm (* 1. *) y // FullForm (* 1.0000000000000002 *) Those look pretty close... let's make sure they're different. I'm not a wizard with the developer tools, but I can export them as IEEE double-precision floating point numbers (which I'd bet is their internal representation): StringJoin @@ IntegerString[Reverse@ToCharacterCode[ExportString[x, "Real64"]], 16, 2] (* 3ff0000000000000 *) StringJoin @@ IntegerString[Reverse@ToCharacterCode[ExportString[y, "Real64"]], 16, 2] (* 3ff0000000000001 *) We can see that they are indeed different. They represent the two numbers: \begin{align} x &= (1.){\underbrace{000 \cdots 000}_\text{51 zeros}}0_2 \times 2^{01111111111_2 - 1023} \equiv 1 \\ y &= (1.){\underbrace{000 \cdots 000}_\text{51 zeros}}1_2 \times 2^{01111111111_2 - 1023} \equiv 1 + \frac{1}{2^{52}} \end{align} That is, x is exactly one, and y is the smallest IEEE double greater than one. Ok, so they're different. Hey Mathematica, you know they're diff- x == y (* True *) Oh. What if we try- x === y (* True *) Hey Python, you use doubles, right? Are you seeing this? >>> 1. == 1.0000000000000002 False Maybe it's because you're using quads? >>> 1. == 1.0000000000000001 True Yeah, I didn't think so. Mathematica, are you sure? I mean, this doesn't seem right... y - x (* 2.22045*10^-16 *) Aha! I knew it! Now let's try this: y - x == 0 (* False *) Success! Now let's just double-check (pun intended): 1.0000000000000001 - 1. (* 0. *) % == 0 (* True *) So you are using double-precision... My question is, Why do Equal and SameQ return True, even though these numbers are obviously different? SameQ ignores the last bit, and Equal ignores the last seven bits! • InternalEqualTolerance and Internal$SameQTolerance. You can search the site for explanations – Michael E2 Mar 10 '15 at 0:17 • @MichaelE2 Yep, just found those in the related questions. Should this one be closed? – 2012rcampion Mar 10 '15 at 0:18 • That's a good question. I didn't find an exact duplicate in my cursory search. But I guess it's in the "Details" of the docs -- e.g., from 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)." I would consider that "easily found in the documentation," I guess. Others might think this is a nice clear question about an idiosyncratic behavior of Mathematica. Your choice, or you could wait and see if the community closes it. – Michael E2 Mar 10 '15 at 0:22 • Yeah, there are nearly infinitely many corners of Mathematica and not enough time to explore them all. (Different users have different notions of "easily found", but still, I think if the answer is clearly explained in the details of the docs for the function, I consider it easily found, even if it's a function I never heard of. But I won't vote to close. I think the issue is important and common enough, that a little extra duplication of the documentation is ok.) – Michael E2 Mar 10 '15 at 0:33 • – Michael E2 Mar 10 '15 at 0:40 ## 2 Answers It seems I found my answer in OleksandrR's comment to this question. He says, Bear in mind Equal applies an extra tolerance in Mathematica. The proper comparison is Block[{Internal$EqualTolerance = -Infinity}, 1 == 1 + $MachineEpsilon] (* False *) Block[{Internal$EqualTolerance = -Infinity}, 1 == 1 + $MachineEpsilon/2] (* True *) In fact, the value of Internal$EqualTolerance * Log2[10] is 7., meaning that it ignores the last seven bits, just as I discovered!

(Analogously, Internal\$SameQTolerance * Log2[10] is 1., i.e. it drops the last bit.)

Note that this is mentioned in the documentation for Equal, under Details:

• 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).
• For numbers below machine precision the required tolerance is reduced in proportion to the precision of the numbers.

However, I never thought to look at it, since (thought) I knew what == means! Lesson learned, always check the documentation, especially if you don't think you need to.

You can define your own "precise equal" using Congruent () (entered as Esc===Esc or \[Congruent]):

Congruent[x_, y_] := Equal @@ SetPrecision[{x, y}, Infinity]

Now

x ≡ y
False