Порядок умножения


Что делает C++ в цепном умножении ?

int a, b, c, d;
// set values
int m = a*b*c*d;
5 4

5 ответов:

Оператор * имеет слева направо ассоциативность:

int m = ((a * b) * c) * d;

Хотя в математике это не имеет значения (умножение является ассоциативным), в случае как C, так и C++ мы можем иметь или не иметь переполнение в зависимости от порядка.

0 * INT_MAX * INT_MAX // 0
INT_MAX * INT_MAX * 0 // overflow

И все становится еще более сложным, если мы рассматриваем типы с плавающей точкой или перегрузку операторов. Смотрите комментарии @delnan и @melpomene.

Да, порядок идет слева направо.

int m = a * b * c * d;

Если вас больше интересует тема порядка вычисления или приоритета операторов, то вы можете быть удивлены, как некоторые операции ++ ведут себя, даже по-разному с версией C.

Http://en.cppreference.com/w/c/language/eval_order

Http://en.cppreference.com/w/c/language/operator_precedence

Нет никакого особого "порядка", он умножается, как показано, слева направо.

int m = a * b * c * d;
Порядок операций вступает в силу при использовании сложения / вычитания с делением / умножением. В противном случае он всегда слева направо. В любом случае, с этим примером решение будет одним и тем же, независимо от того, в каком порядке они находились.

В этом случае порядок идет слева направо где

int m=a*b*c*d;

Здесь сначала вычисляется (a*b), затем результат умножается на c, а затем на d, как показано в скобках:

int m=(((a*b)*c)*d);

Порядок номинально слева направо. Но оптимизаторы в компиляторах C++, которые я использовал, не стесняются изменять этот порядок для типов данных, которые, как им кажется, они понимают. Если вы перегружаете оператора* и оптимизатор не может видеть вашу перегрузку, то он не может изменить порядок. Но когда вы умножаете последовательность вещей (переменные, константы, результаты функций и т. д.) чей тип является двойным, оптимизатор может использовать ассоциативное и коммутативное свойство умножения вещественных чисел, как если бы это было истина в плавающем или двойном умножении. Это может привести к некоторым сюрпризам, когда для вас важны наименее значимые биты.

Насколько я понимаю, стандарт допускает такую оптимизацию, но я далек от "языкового юриста", поэтому моя лучшая догадка о стандарте не является высказыванием, которому можно доверять (по сравнению с моим опытом о том, что на самом деле делают компиляторы).