У меня есть проект, в котором я имею дело с большими числами (ns-timestamps), которые не помещаются в целое число. Поэтому я хочу использовать, например, int64_t и в настоящее время пишу контрольный пример (да!).
Чтобы проверить поведение большого числа, я начал с чего-то вроде
int64_t val = 2*std::numeric_limits<int>::max();
qDebug() << "long val" << val;
который возвращается
long val -2
(так же, как если бы я определил val как int).
Но если я напишу
int64_t val = std::numeric_limits<int>::max();
val *= 2;
qDebug() << "long val" << val;
я получил
long val 4294967294
который выглядит правильно.
Так что для меня это выглядит так, как будто 2*max()
сначала сохраняется в целое число (обрезается на этом шаге), а затем копируется в int64
, Почему это происходит? Компилятор знает, что результат имеет тип int64
так что это 2*max()
должен соответствовать прямо.
Так что для меня это выглядит так, как будто
2*max()
сначала сохраняется в целое число (обрезается на этом шаге), а затем копируется вint64
Это абсолютно правильно. Согласно спецификации языка, когда все части выражения помещаются в int
Вычисление выполняется в целых числах. В вашем случае оба 2
а также max()
подходит в int
Таким образом, умножение выполняется в целых числах, вызывая переполнение.
Компилятор знает, что результат имеет тип
int64
так что это2*max()
должен соответствовать прямо.
Результат, которому присваивается выражение, в этой ситуации не имеет значения: само выражение направляет способ его вычисления. Вы можете достичь того же результата, применяя max()
в int64
:
int64_t val = 2*(int64_t)std::numeric_limits<int>::max();