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.
In the case of floating-point numbers, the relational operator (==) does not produce correct output, this is due to the internal precision errors in rounding up floating-point numbers. In the above example, we can see the inaccuracy in comparing two floating-point numbers using “==” operator.
To compare two floating point values, we have to consider the precision in to the comparison. For example, if two numbers are 3.1428 and 3.1415, then they are same up to the precision 0.01, but after that, like 0.001 they are not same.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With