简体   繁体   English

为什么浮点数的`a * b`和`a *= b`的结果不同

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

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.我从一个标记为重复的问题中借用了这段代码,然后删除了1 ,但是因为我无法找到与其完全相同的重复项,所以我想为此创建一个新问题。

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? ).所以人们可以期望那些应该有相同的结果,因为a *= b被视为a = a * b的捷径( +=(加等于)如何工作? )。

But the outcome of the two snippets can be different.但是这两个片段的结果可能不同。

This is because *= has a lower precedence than * or / as per MDN .这是因为*=根据MDN的优先级低于* or /

So, when we write a *= 1 / b it is not equal to a = a * 1 / b;因此,当我们写a *= 1 / b时,它不等于a = a * 1 / b;

In case of a *= 1/b It will calculate 1/b first then multiply a with the result.a *= 1/b情况下,它将首先计算 1/b,然后将 a 与结果相乘。 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 .对于a = a * 1 / b ,因为*/具有相同的优先级并且它们从左到右计算, a * 1将首先计算,然后将结果除以b

Update (Thanks to @Felix Kling) This is how it works to be precise,更新(感谢@Felix Kling)这是精确的工作方式,

a *= 1/b actually implicitly groups the right hand side, therefore, it becomes, a = a * (1/b) . a *= 1/b 实际上隐式地将右侧分组,因此,它变为a = a * (1/b) That is why 1/b is evaluated first and then multiplied by a .这就是为什么首先评估1/b然后乘以a原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM