I'm getting results that are sensitive to where I place parentheses with respect to operations that are associative1 (and should thus be insensitive to such placement). For example, if I define2

<< Units`; << PhysicalConstants`;
stellarDayTextbook = 1/(1/Day + 1/Convert[SiderealYear, Day])

and then calculate

1/stellarDayTextbook - 1/Day - 1/Convert[SiderealYear, Day]

I get precisely zero, as expected. But if I add parentheses

(1/stellarDayTextbook - 1/Day) - 1/Convert[SiderealYear, Day]

I get


What's causing this?

1. Remember, this isn't C, it's math: "subtraction" of $x$ is just the addition of $-x$. Check TreeForm.

2. I realize this isn't the definition of a "stellar day", but merely a textbook approximation. The distinction is not material to the question.

  • $\begingroup$ Subtraction is associative? en.wikipedia.org/wiki/Associative_property $\endgroup$ Nov 13 '12 at 16:01
  • $\begingroup$ @alancalvitti: Ok, ok: go ahead and replace all the - with +-. $\endgroup$
    – orome
    Nov 13 '12 at 16:05
  • 5
    $\begingroup$ Just numerical roundoff error here. We know the order of evaluation for the parenthesized version, and clearly the order is different for the unparenthesized version. Use Chop on the result to get rid of the error. $\endgroup$
    – murray
    Nov 13 '12 at 16:07
  • 6
    $\begingroup$ In any case, floating point operations are not necessarily associative/distributive, even if the underlying mathematical operations are. $\endgroup$
    – rm -rf
    Nov 13 '12 at 16:26
  • 2
    $\begingroup$ Actually just like in C, addition of floating point (inexact) numbers isn't associative in Mathematica either ... $\endgroup$
    – Szabolcs
    Nov 13 '12 at 18:53

What you're seeing here is just the impreciseness of floating point arithmetic. It is important to remember that floating point operations are not associative or distributive even if the underlying mathematical operations are. A very simple example demonstrating the lack of associativity:

1. + (1.*^20 - 1.*^20)
(* 1. *)

(1. + 1.*^20) - 1.*^20
(* 0. *)

Much has been said and written about this topic over the years, so instead of repeating, I'll just link you to a good article to read on the subject: D. Goldberg, "What every computer scientist should know about floating-point arithmetic," ACM Comput. Surv. 23, 1 (March 1991), 5-48

  • $\begingroup$ As discussed in the comments above, it's interesting that Mathematica does not take advantage of its knowledge of expression structure to produce a more accurate result. $\endgroup$
    – orome
    Jan 12 '14 at 2:30
  • 1
    $\begingroup$ @raxacoricofallapatorius its does If one uses exact numbers. (1 + 1*^20) - 1*^20 gives 1 $\endgroup$
    – Nasser
    Jan 12 '14 at 2:34
  • $\begingroup$ @Nasser: But only because those calculations are exact, not because Mathematica is removing the parentheses symbolically. $\endgroup$
    – orome
    Jan 12 '14 at 2:53
  • 1
    $\begingroup$ @raxacoricofallapatorius Mathematica is not magic. It neither knows what you intended to achieve nor can it feasibly infer that from some kind of analysis of the sum total of all system, package, and user code that it processes. Anyway, this got my upvote for an excellent reference. $\endgroup$ Jan 12 '14 at 2:59
  • 1
    $\begingroup$ @raxacoricofallapatorius not necessarily, when you are working with floating point values. Mathematica is essentially stuck between those who want floating point numbers to behave as an exact analogy to the reals, and those who insist that they are legitimate mathematical objects in their own right, with their own special rules of algebra. I think the compromises that have been made to accommodate both of these classes of users are mostly reasonable, but there are obviously limits to what can be done. The important point is to be aware of what you are really doing so as not to be surprised. $\endgroup$ Jan 12 '14 at 4:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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