Почему это отличается между -2147483648 и (int) -2147483648

Когда я запускаю следующий код под Windows7 x64, скомпилированный с GCC MinGW, результат, кажется, недооценен:

cout<<-2147483648 ;    //Output: 2147483648

но когда я назначил его целочисленной переменной или просто преобразовал в тип int:

cout<<(int)-2147483648 ; //Output: -2147483648

Итак, что не так с предыдущей версией моего кода? Разве это не тип int? или какова нижняя граница Integer?
Большое спасибо.

8

Решение

2147483648 не вписывается в int или long в вашей системе, поэтому он рассматривается как константа типа unsigned long. (Редактировать: как указано в комментариях, в стандартном C ++ это неопределенное поведение, но ваш компилятор принимает его как расширение.) Возможно отрицание целочисленного значения без знака, но в результате получается другое целочисленное значение без знака, а не отрицательное число. Отрицание 2147483648UL выдает 2147483648UL (при условии, что, как и в вашей системе, длинная без знака является 32-битным типом).

Приведение к int создает результат, определенный реализацией, обычно результат, который вы видите, но не обязательно. Вы можете получить желаемый результат без каких-либо преобразований, написав -2147483647 — 1.

11

Другие решения

Итак, что не так с предыдущей версией моего кода?

Предположительно, вы используете компилятор до 2011 года и в вашей системе long имеет 32 бита. Значение (-231) не гарантированно вписывается в long, так что это может переполниться. Это дает неопределенное поведение, так что вы можете видеть что угодно.

Наиболее вероятное объяснение конкретного значения, которое вы видите (231) заключается в том, что при отсутствии определенного поведения в C ++ ваш компилятор использует старые правила C90 и преобразует значение в unsigned long,

Разве это не тип int?

До 2011 года это было int если значение представлено int, иначе longс неопределенным поведением, если этого недостаточно. C ++ 11 добавляет long long тип и позволяет использовать его для целочисленных литералов, если long недостаточно велик

или какова нижняя граница Integer?

Целочисленные типы со знаком с N битами имеют диапазон не менее -2(N-1)+От 1 до 2(N-1)-1. Ваше значение -231, который просто вне диапазона для 32-битного типа со знаком.

Язык не определяет точный размер целочисленных типов; только то int должно иметь не менее 16 бит, long минимум 32, а (с 2011 года) long long не менее 64

3

Прежде всего, важно понимать, что нет отрицательных целочисленных литералов.

Другие объяснили, почему конкретный компилятор OP ведет себя так, как он. Но для записи, это то, что компилятор должен сделать между строк в 32-битной системе:

  • У вас есть номер 2147483648, который не может поместиться в 32-битной подписи int формата дополнения двух.
  • Поскольку это десятичное число (без суффикса U, L или аналогичного), компилятор проверяет свою внутреннюю таблицу типов (1) на наличие такой целочисленной константы. Это работает так: попробуйте вписать его в int, если это не подходит, попробуйте long, если он там тоже не подходит, попробуйте long long, если это не подходит там, у нас есть неопределенное поведение. Компилятор C или C ++ в соответствии с последним стандартом не попытаться вписать его в неподписанные типы.
  • В этом конкретном случае число не вписывается в int ни в longпоэтому компилятор решает использовать long long как тип для буквального.
  • Затем вы используете унарный оператор минус для этого литерала, заканчивающийся числом -2147483648. По иронии судьбы это будет соответствовать подписанному int формата дополнения до двух, но уже слишком поздно менять тип, компилятор уже выбрал long long как тип.

(1) Эта «внутренняя таблица» выглядит иначе, если у вас есть беззнаковый суффикс или если у вас есть шестнадцатеричный формат и т. Д. Если есть беззнаковый суффикс, он будет только проверять, соответствует ли число беззнаковым числам. Если есть шестнадцатеричная запись (но без суффикса), она проверит int, затем unsigned int, затем long и так далее.

2

На самом деле, я нашел объяснение из pdf-файла CS: APP, которое идеально подходит для решения, вы можете скачать его здесь. http://www.csapp.cs.cmu.edu/public/waside/waside-tmin.pdf

0
По вопросам рекламы [email protected]