Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

javascript

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.

like image 723
t.niese Avatar asked Dec 16 '20 10:12

t.niese


People also ask

Why is it a problem to compare two floating point numbers?

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.

How do you compare two floating point numbers?

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.


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.

like image 50
sabbir.alam Avatar answered Oct 22 '22 03:10

sabbir.alam