交换数学运算的顺序

Order of commutative mathematical operations

我有一个好奇的问题(在阅读一段粗略的代码时自己问)。让我们看看表达式:

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

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

标准是哪一段定义的?

基于standard

[intro.abstract] - 注释 7 (non-normative):

Operators can be regrouped according to the usual mathematical rules only where the operators really are associative or commutative.

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

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

一句话-是的。

您正在寻找的 属性 称为运算符关联性。它定义了相同优先级的运算符(例如 */)在没有括号时如何分组和排序。

在您的例子中,*/ 具有相同的优先级,并且都是 left-associative - 即,它们是从左到右计算的。这意味着 c 将乘以 d,然后乘以 e,然后乘以 2(这将通过浮点运算完成,因为您double 乘以 int 字面量),然后除以 3(再次使用浮点运算),最后乘以 f.

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

*/具有相同的优先级,并且是left-to-right结合的,这意味着

a*b*c*d

被解析为

((a*b)*c)*d

如果将任何 * 替换为 /,情况也是如此。

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