12

I borrowed this code from a question that was marked as duplicate and then deleted 1, but because I was not able to find an exact duplicate to it I would like to create a new question for that.

I'm aware of the problems with floating-point arithmetic (Is floating point math broken?), but this special case is still interesting.

The following two snippets look seemingly equal:

let a = 860.42065
a *= 1/860.42065
console.log(a);

let a = 860.42065
a = a * 1/860.42065
console.log(a);

So one could expect that those should have the same outcome because a *= b is seen as a shortcut for a = a * b (How does += (plus equal) work?).

But the outcome of the two snippets can be different.

t.niese
  • 39,256
  • 9
  • 74
  • 101

1 Answers1

9

This is because *= has a lower precedence than * or / as per MDN.

So, when we write a *= 1 / b it is not equal to a = a * 1 / b;

In case of a *= 1/b It will calculate 1/b first then multiply a with the result. On the other hand,

For a = a * 1 / b , as * and / are of same precedence and they evaluate from left to right, a * 1 will be evaluated first then the result will be divided by b.

Update (Thanks to @Felix Kling) This is how it works to be precise,

a *= 1/b actually implicitly groups the right hand side, therefore, it becomes, a = a * (1/b). That is why 1/b is evaluated first and then multiplied by a.

Md Sabbir Alam
  • 4,937
  • 3
  • 15
  • 30
  • Wile I can see how one might take the precedence of `*=` into account, I think it's a bit confusing/misleading, because if `*=` had a higher precedence, then it would be equivalent to `a = a * (1/b)` either (`(a *= 1)/b` would leave `a` unchanged). – Felix Kling Dec 16 '20 at 11:01
  • To proof my point, consider `+=`: `a += 1/b` is in fact equivalent to `a = a + 1/b` even though `+=` has a lower precedence than `+` or `/`. What matters really is just the precedence and associativity of "underlying" operators involved. The assignment is only relevant insofar that the "combined" assignment "implicitly" groups the right hand side. – Felix Kling Dec 16 '20 at 11:05
  • Ah I see, Thanks @Felix Kling. You mean, `a*=1/b ` is actually equivalent to `a = a*(1/b)` is that right? – Md Sabbir Alam Dec 16 '20 at 11:17