Message Boards Message Boards

GROUPS:

Result of Equal with multiple arguments

Posted 2 months ago
598 Views
|
9 Replies
|
4 Total Likes
|

In the documentation it is written: "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)." and "e1==e2==e3 gives True if all the ei are equal."

This works fine with an equation of two arguments in all combinations, but it fails with a comparison of three values, but why?

a = 0.999999999999991;
b = 1.000000000000000;
c = 1.000000000000001;
Print[a == b, " : a==b is True"]
Print[b == c, " : b==c is True"]
Print[a == c, " : a==c is also True"]
Print[a == b == c, " : a==b==c should be True as well?"]

True : a==b is True

True : b==c is True

True : a==c is also True

False : a==b==c should be True as well?

I use Mathematica 10.0.2.0 on Windows 7 (x64)

9 Replies

Interesting question! I'm not sure how it works for varargs… very strange it works like this, smells like a bug?!

Posted 2 months ago

No more comments? Where can I post a bug report?

Where can I post a bug report?

http://support.wolfram.com is not that hard to find ...

I am not going to comment on whether this should be considered a bug or not, but I will put one question to the community:

What would be a reasonable implementation in your opinion?

Keep in mind that equality with tolerance is not transitive, and that doing all pairwise comparisons is slow ( $O(n^2)$ would not be nice). One could do Rounding and then do exact comparison, but what if two very close values fall on two sides of the rounding boundary?

I'm quite curious about how this is implemented.

The order still doesn't matter fortunately:

a == b == c
a == c == b
b == c == a
b == a == c
c == a == b
c == b == a

all give the same…

Maybe the one-bit-off doesn't work anymore for the general vararg?

In my System (Mma 7.0) a == b == c gives True.

In my System (Mma 7.0) a == b == c gives True.

I checked several versions. v10.0 and later give False. v7, v8 and v9 give True. Our institutional cluster even has v6 installed, but it no longer starts up on modern Linux.

[removed, because I read the question wrong]

It's weird that it does this:

In[91]:= Equal @@ ({a, b, c} - 0.1)
Out[91]= False

In[92]:= Equal @@ ({a, b, c} - 0.2)
Out[92]= True

In[93]:= Equal @@ ({a, b, c} - 0.3)
Out[93]= False

In[94]:= Equal @@ ({a, b, c} + 0.00000005551146)
Out[94]= True

In[95]:= Equal @@ ({a, b, c} + 0.00000005551145)
Out[95]= False

I don't know the exact meaning of $EqualTolerance, but its value is 7 bits.

In[108]:= Internal`$EqualTolerance/Log10[2]
Out[108]= 7.

What does that mean? It is not sufficient to compare the last 7 (binary) digits. Using a decimal example, the last 1 digit of 999 and 1000 are not the same even though their difference is only 1. Similarly, a<1 but c>b>1.

If we offset them, we get rid of this problem.

What is the difference between ({a, b, c} + 0.00000005551145) and ({a, b, c} + 0.00000005551146) (see my last post)?

Let's see their binary digits:

enter image description here

Notice that the one that returns False has 7 digits of difference, the other only 6. 7 is exactly the threshold. The behaviour must have something to do with this.

But I still do not understand it.

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract