# Floating point addition not associative

Can anybody explain the following behavior?

x = 0.2 + (0.3 + 0.1);
y = (0.2 + 0.3) + 0.1;
x == y (* -> True *)


But actually the variables do not exactly contain the same values:

x // FullForm (* -> 0.6000000000000001 *)
y // FullForm (* -> 0.6 *)


The example was taken from Mike Croucher's blog entry.

-
The answer to this question was actually mentioned in the link you provided, read it again. –  DumpsterDoofus Mar 2 at 4:10

As rasher and the documentation both say, Equal has a certain level of fuzziness. The same is true of SameQ, though it has a more stringent tolerance. The following computations are all done with machine precision numbers. Similar things should hold with arbitrary precision numbers but the analysis might be trickier.

(* 12 zeros, difference = 1.00142*10^(-13) *)
1.0000000000001 == 1.0000000000002
(* Out: False *)

(* 13 zeros, difference = 9.992*10^(-15) *)
1.00000000000001 == 1.00000000000002
(* Out: True *)

(* Same as last with SameQ *)
1.00000000000001 === 1.00000000000002
(*Out: False *)

(* 15 zeros, difference = 2.22045*10^(-16) *)
1.0000000000000001 === 1.0000000000000002
(* Out: True *)


It might also be worth mentioning that more traditional floating point comparisons can be easily emulated. For example, since the "fuzziness" is based on Precision, we can check if the difference is equal to zero.

x = 0.2 + (0.3 + 0.1);
y = (0.2 + 0.3) + 0.1;
x == y
x - y == 0.0

(* Out1: True *)
(* Out2: False *)


Certain compiler switches also make comparisons more C-like.

test1 = Compile[{}, 0.2 + (0.3 + 0.1) == (0.2 + 0.3) + 0.1];
test2 = Compile[{}, 0.2 + (0.3 + 0.1) == (0.2 + 0.3) + 0.1,
RuntimeOptions -> "Speed"];
test1[]
test2[]

(* Out1: True *)
(* Out2: False *)

-

See the documentation for Equal. There is a tolerance for inexact numbers. The order of operations combined with precision of targets can affect whether things fall "in" or "out" of tolerance. See specifically the "Possible Issues" section in the documents for Equal. As far as why results themselves differ in FP arithmetic, there is no better source than the paper referenced in the blog entry.

-
More generally one might comment that floating point values are in fact considered "inexact" (i.e. as approximate reals) in Mathematica, whereas all other systems (as far as I know) treat them as the exact rationals that they really are. This model is precisely the motivation for the tolerance on floating point comparisons, as well as explaining a number of other numerical oddities of Mathematica. Unfortunately I find that this fundamental difference relative to anything else the user is likely to have encountered is not really made quite clear enough in the documentation. –  Oleksandr R. Mar 2 at 3:50
I don't follow this. Matlab, for example, will very likely give the same results as Mathematica when doing arithmetic on machine doubles. Is your claim otherwise? Or that this happens, but that comparisons are done differently? –  Daniel Lichtblau Mar 2 at 20:54
@DanielLichtblau: Is above directed at me? –  rasher Mar 2 at 22:43
@DanielLichtblau I'm pretty sure that OP understood the blog post and now wants to know why Mathematica considers two different numbers as being equal, unlike all(?) other systems. A large part of the problem, IMO, is that the documentation generally treats Mathematica's numerical model as received wisdom, never really pointing out that it is in fact the result of a highly non-standard (though arguably advantageous in some situations) design choice. –  Oleksandr R. Mar 2 at 23:47
My apologies, I should have made clear that my note was a question for @Oleksandr R. His response clarified what he meant. Yes, the issue at heart is how Mathematica does equality testing, and yes, it's not standard insofar as most or all other programs do it differently. [I had thought there might be a claim to the effect that underlying arithmetic was being done differently. It isn't, and there was no such claim.] –  Daniel Lichtblau Mar 3 at 15:37