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