Проблема переполнения Int64_t - PullRequest
2 голосов
/ 18 сентября 2011

Я использую Eclipse CDT - Cross G ++ Complier (MinGW / msys) в Windows 7, это мой код:

int64_t y = 1024 * 1024 * 1024 * 4;
std::cout << "type id: " << typeid(y).name() << "; value: " << y << "; size of y: " << sizeof(y) << std::endl;

(Предупреждение IDE: "переполнение целого числа".)

И вывод:

"type id: x; value: 0; size of y: 8"

Я не понимаю, почему размер y равен 8 байтам, а значение равно 0.

Спасибо за вашу помощь.

Ответы [ 3 ]

3 голосов
/ 18 сентября 2011

Вы должны явно преобразовать литерал в int64_t:

int64_t y = (int64_t)1024 * 1024 * 1024 * 4;

, так как 1024 * 1024 * 1024 * 4 литерал int, а не int64_t.

2 голосов
/ 18 сентября 2011

Тот факт, что вы присваиваете результат int64_t, не имеет значения. Все, что имеет значение, это то, что при умножении двух значений типа int результат также имеет тип int. Поскольку все 1024, 1024, 1024 и 4 являются константами типа int, результирующий временный продукт вычисляется как int, который переполняется.

Решение состоит в том, чтобы сделать по крайней мере одну из этих констант int64_t. Произведение int64_t с int является int64_t, поэтому 64-битная скорость будет каскадно распространяться на весь продукт. Вы можете сделать это либо с явным приведением, либо с целочисленным суффиксом :

int64_t y = (int64_t)1024 * 1024 * 1024 * 4;  // explicit cast
int64_t y = 1024ll * 1024 * 1024 * 4;  // integer suffix 'll'

Суффикс ll (или эквивалентно LL) после целочисленной константы говорит: «Это значение действительно long long». Также существует суффикс ull (или ULL), который используется для unsigned long long. Также обратите внимание, что стандарт языка C гарантирует, что значение long long не менее 64 бит.

1 голос
/ 18 сентября 2011

Когда вы пишете «1024» в выражении C ++, как и в вашем вопросе, вы пишете целочисленный литерал , размер которого составляет 4 байта, т.е. 32 бита (как его тип будет int или unsigned int), поэтому последнее умножение на 4 приводит к переполнению 4-байтового целого числа. Попробуйте вместо этого:

int64_t y = ((int64_t)1024) * 1024 * 1024 * 4;
...