6
$\begingroup$

Consider the following two numbers:

num1=0.0006000000000000001`;
num2=0.0006000000000000003`;

num2 appeared from num1 as a result of some compiled code with RuntimeOptions->"Speed".

Their direct comparison returns

num1==num2

True

However,

{num1, num2} // DeleteDuplicates

keeps both the numbers.

Why do these two operations work at different precision levels?

P.S. Mathematica 13.2 on Windows 11.

$\endgroup$
2
  • 5
    $\begingroup$ To be clear, this is not a bug. $\endgroup$ Commented Feb 19 at 3:17
  • 2
    $\begingroup$ @DanielLichtblau : formally, yes. But in practice, I spent a lot of time trying to uncover errors in my code because of this mismatch. $\endgroup$ Commented Feb 19 at 11:12

3 Answers 3

8
$\begingroup$

Because default DeleteDuplicates uses === and not == (i.e SameQ). (unless overriden)

You can see this

num1 = 0.0006000000000000001`;
num2 = 0.0006000000000000003`;
DeleteDuplicates[{num1, num2}, (#1 === #2) &]

Mathematica graphics

Which is same as

DeleteDuplicates[{num1, num2}]

Mathematica graphics

But

DeleteDuplicates[{num1, num2}, (#1 == #2) &]

Mathematica graphics

SameQ checks the two objects are identical in the sense that they occupy same memory location they have identical FullForm

enter image description here

While for ==

enter image description here

So when comparing numbers, use == and when comparing symbolic expressions use ===

$\endgroup$
1
  • $\begingroup$ @"SameQ checks the two objects are identical in the sense that they occupy same memory location" Not quite following the reasoning behind this statement, but I'd say that is not the case. $\endgroup$
    – ilian
    Commented Feb 18 at 16:02
7
$\begingroup$

From the help of Equal ( "==" ): "Numbers with machine precision (MachinePrecision) or greater are considered equal if they differ in at most their last seven binary digits."

As Nasser already mentioned, "DeleteDuplicates" uses "SameQ". From the help of "SameQ": "SameQ requires exact correspondence between expressions, except that it still considers Real numbers equal if they differ in their last binary digit."

Now, as "==" is less strict than "===" you get:

num1 == num2

True

and

num1 === num2 

False

Finally, consider the binary representation of num1 and num2 (note that $MachinePrecision on my machine is:15.954589770191003 )

num1 = 0.0006000000000000001`15.954589770191003;
num2 = 0.0006000000000000003`15.954589770191003;
BaseForm[num1, 2]
BaseForm[num2, 2]

enter image description here

As you see, the numbers differ in the last 3 digits.

$\endgroup$
1
3
$\begingroup$

Warning!!! If you evaluate this your believe in logical reasoning may be ruined ;-)

n1 = 0.59999999999999993;
n2 = 0.6000000000000001;
n3 = 0.6000000000000002;

{n1 == n2 == n3}
{n1 === n2, n2 === n3, n1 === n3}

{True}
{True, True, False}

Clue:

Real numbers are considered SameQ if they differ only in their last binary digit
(the statement is not phrased well, it should be understood so that they can differ by +/- 1 least significant bit)

RealDigits[n1, 2]
RealDigits[n2, 2]
RealDigits[n3, 2]

$\endgroup$
2
  • 1
    $\begingroup$ This is why it's important to be aware of multi-arg SameQ: n1 === n2 === n3 (*False*). SameQ isn't always transitive when it comes to numerical quantities and the multi-arg use case can account for this. $\endgroup$ Commented Feb 19 at 12:22
  • 1
    $\begingroup$ @Sjoerd Smit: It is not property of SameQ alone, it is similar with Equal used on reals numbers. $\endgroup$ Commented Feb 19 at 12:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.