Когда я запускаю следующий код под Windows7 x64, скомпилированный с GCC MinGW, результат, кажется, недооценен:
cout<<-2147483648 ; //Output: 2147483648
но когда я назначил его целочисленной переменной или просто преобразовал в тип int:
cout<<(int)-2147483648 ; //Output: -2147483648
Итак, что не так с предыдущей версией моего кода? Разве это не тип int? или какова нижняя граница Integer?
Большое спасибо.
2147483648 не вписывается в int или long в вашей системе, поэтому он рассматривается как константа типа unsigned long. (Редактировать: как указано в комментариях, в стандартном C ++ это неопределенное поведение, но ваш компилятор принимает его как расширение.) Возможно отрицание целочисленного значения без знака, но в результате получается другое целочисленное значение без знака, а не отрицательное число. Отрицание 2147483648UL выдает 2147483648UL (при условии, что, как и в вашей системе, длинная без знака является 32-битным типом).
Приведение к int
создает результат, определенный реализацией, обычно результат, который вы видите, но не обязательно. Вы можете получить желаемый результат без каких-либо преобразований, написав -2147483647 — 1.
Итак, что не так с предыдущей версией моего кода?
Предположительно, вы используете компилятор до 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
Прежде всего, важно понимать, что нет отрицательных целочисленных литералов.
Другие объяснили, почему конкретный компилятор OP ведет себя так, как он. Но для записи, это то, что компилятор должен сделать между строк в 32-битной системе:
int
формата дополнения двух.int
, если это не подходит, попробуйте long
, если он там тоже не подходит, попробуйте long long
, если это не подходит там, у нас есть неопределенное поведение. Компилятор C или C ++ в соответствии с последним стандартом не попытаться вписать его в неподписанные типы.int
ни в long
поэтому компилятор решает использовать long long
как тип для буквального.long long
как тип.(1) Эта «внутренняя таблица» выглядит иначе, если у вас есть беззнаковый суффикс или если у вас есть шестнадцатеричный формат и т. Д. Если есть беззнаковый суффикс, он будет только проверять, соответствует ли число беззнаковым числам. Если есть шестнадцатеричная запись (но без суффикса), она проверит int, затем unsigned int, затем long и так далее.
На самом деле, я нашел объяснение из pdf-файла CS: APP, которое идеально подходит для решения, вы можете скачать его здесь. http://www.csapp.cs.cmu.edu/public/waside/waside-tmin.pdf