Когда C ++ 11 выполняет преобразования арифметических типов относительно приоритета операторов? - PullRequest
0 голосов
/ 10 января 2019

Если у меня есть следующий код:

double compute(double val1,
               int32_t val2,
               int32_t val3,
               int32_t val4) {
  return val1 + val2 * val3 * val4;
}

Как язык C ++ 11 указывает, что умножение должно выполняться? Например, val1, val2 и val3 умножены на 32-разрядные целые числа в соответствии с приоритетом оператора, возможно переполнены, а затем преобразованы в двойное число, или они умножены на двойное число?

В целом, что конкретно говорит стандарт по этому вопросу? Изменилось ли это в последующих версиях C ++ (например, C ++ 17)?

1 Ответ

0 голосов
/ 10 января 2019

Выражение

val1 + val2 * val3 * val4

имеет тип double, но часть умножения имеет тип int32_t. Если мы применяем правила его оценки, мы получаем

val1 + (val2 * val3 * val4)

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

Чтобы умножение происходило как double, вам нужно привести либо val2, либо val3 к двойному, что сделает всю часть умножения оцененной как double. Это будет выглядеть как

val1 + (static_cast<double>(val2) * val3 * val4)

скобки не нужны, но мне нравится использовать их для отображения группировки

...