Why is the result of `a * b` and `a *= b` for floating point numbers different

Viewed 116

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.

1 Answers

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.

Related