交换数学运算的顺序

时间:2018-03-27 07:29:22

标签: c++ operators language-lawyer type-promotion

我遇到了一个奇怪的问题(在阅读原始代码时自己问自己)。让我们来看看表达式:

double a =  c*d*e*2/3*f;

其中c,d,e,f是类型double的初始化变量。标准是否保证将其视为c*d*e*2(双重结果),然后除以3并乘以f(或某些类似行为)。显然,2/3被计算为0是不可取的。

标准的哪一段定义了?

3 个答案:

答案 0 :(得分:2)

基于standard

[intro.abstract] - 注7 (非规范性):

  

操作员可以按照通常的数学规则重新组合   只有运营商真正联想或可交换的地方。

MDAS的数学规则是从左到右(考虑到运算符的关联性和优先级)。所以评估如下:

(((((c * d) * e) * 2) / 3) * f)

答案 1 :(得分:2)

总之 - 是的。

您正在寻找的属性称为运营商关联性。它定义了当括号不存在时,如何对相同优先级的运算符(例如*/)进行分组和排序。

在您的情况下,*/都具有相同的优先级,并且都是左关联的 - 即,它们是从左到右进行评估的。这意味着c将乘以d,然后是e的结果,然后是2的结果(这将通过浮点运算完成,因为您&#39} ;将double乘以int字面值,然后除以3(再次使用浮点运算),最后乘以f

有关其他信息,请参阅this cppreference page

答案 2 :(得分:1)

*/都具有相同的优先级,并且是从左到右的关联,这意味着

a*b*c*d

被解析为

((a*b)*c)*d

如果您使用*替换任何/,情况也是如此。

来源:http://en.cppreference.com/w/cpp/language/operator_precedence