交换数学运算的顺序
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
我有一个好奇的问题(在阅读一段粗略的代码时自己问)。让我们看看表达式:
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