Порядок коммутативных математических операций

У меня возник интересный вопрос (я задаю его сам, читая сырой кусок кода). Давайте посмотрим на выражение:

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

где c, d, e, f — инициализированные переменные типа double, Стандартная гарантия, что это будет рассматриваться как c*d*e*2 (двойной результат) затем делится на 3 и умножить на f (или похожее поведение). Очевидно, что 2/3, рассчитываемое на 0, нежелательно.

Какой параграф стандарта определяет это?

0

Решение

На основе стандарт

[intro.abstract] — Примечание 7 (Ненормативные):

Операторы могут быть перегруппированы в соответствии с обычными математическими правилами
только там, где операторы действительно ассоциативны или коммутативны.

Математическое правило для MDAS слева направо (с учетом ассоциативности и приоритета операторов). Так это оценивается следующим образом:

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

Другие решения

Одним словом — да.

Свойство, которое вы ищете, называется ассоциативностью операторов. Он определяет, как операторы с одинаковым приоритетом (например, * а также /) группируются и упорядочиваются при отсутствии скобок.

В вашем случае оба * а также / имеют одинаковый приоритет и оба являются левоассоциативными — то есть они оцениваются слева направо. Что значит c будет умножено на dто результат по eто результат по 2 (что будет сделано с помощью арифметики с плавающей запятой, так как вы умножаете double по int буквально), затем делится на 3 (снова с использованием арифметики с плавающей запятой) и, наконец, умножается на f,

Увидеть эта страница cppreference для дополнительной информации.

2

И то и другое * а также / имеют одинаковый приоритет и являются ассоциативными слева направо, это означает, что

a*b*c*d

анализируется как

((a*b)*c)*d

и то же самое верно, если вы замените любой из * с /,

Источник: http://en.cppreference.com/w/cpp/language/operator_precedence

1
По вопросам рекламы [email protected]