Что делает C ++ в цепочечном умножении?
int a, b, c, d;
// set values
int m = a*b*c*d;
оператор *
имеет слева направо ассоциативность:
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.
Не существует какого-либо специального «порядка», который он умножает, как показано слева направо.
int m = a * b * c * d;
Порядок операций вступает в силу при использовании сложения / вычитания с делением / умножением. В противном случае это всегда слева направо. Независимо от примера, решение будет одинаковым независимо от того, в каком порядке они находятся.
Порядок слева направо в этом случае
где
int m=a*b*c*d;
Здесь сначала вычисляется (a * b), затем результат умножается на c, а затем d, как показано в скобках:
int m=(((a*b)*c)*d);
Порядок номинально слева направо. Но оптимизаторы в компиляторах C ++, которые я использовал, не стесняются изменять этот порядок для типов данных, которые, по их мнению, они понимают. Если вы перегрузите оператор *, а оптимизатор не сможет увидеть вашу перегрузку, он не сможет изменить порядок. Но когда вы умножаете последовательность вещей (переменные, константы, результаты функций и т. Д.), Тип которых double, оптимизатор может использовать ассоциативное и коммутативное свойство умножения действительного числа, как если бы оно было истинным при умножении с плавающей запятой или двойном умножении. Это может привести к некоторым неожиданностям, когда для вас важны наименее значимые биты.
Насколько я понимаю, стандарт допускает такую оптимизацию, но я далеко не «языковой адвокат», поэтому мое лучшее предположение о стандарте — это не заявление, которому нужно доверять (по сравнению с моим опытом в том, что на самом деле делают компиляторы).