Понимание 2^31 и -2^31 целочисленного продвижения
#include <stdio.h>
int main() {
printf("sizeof(int): %zu\n", sizeof(int));
printf("%d\n", 2147483648u > -2147483648);
printf("%d\n", ((unsigned int)2147483648u) > ((int)-2147483648));
printf("%d\n", 2147483648u != -2147483648);
printf("%d\n", ((unsigned int)2147483648u) != ((int)-2147483648));
return 0;
}
Вывод этого кода на C и C++, на cygwin64 и на машине rhel6.4 с gcc 5.2.0:
sizeof(int): 4
1
0
1
0
Согласно " Целым акциям", 2147483648u
будет иметь тип unsigned int
(даже без u
суффикс) и -2147483648
типа int
(по-прежнему). Почему разные результаты с явным приведением?
Согласно " Обычным арифметическим преобразованиям", этот параграф применяется:
В противном случае подпись отличается: если операнд с беззнаковым типом имеет ранг преобразования, больший или равный рангу типа подписанного операнда, то операнд с подписанным типом неявно преобразуется в тип без знака
Это означает, что правильный результат выглядит так:
2147483648u > 2147483648u
2147483648u != 2147483648u
были выполнены, потому что в 32 битах со знаком -2^31 и без знака 2 ^ 31 имеют одинаковое представление. Другими словами, результат с приведением верен. Что здесь происходит?
У меня такое ощущение, что каким-то образом целочисленное продвижение более высокого ранга применяется без разыгрыша, поэтому я получаю, например, 64-разрядное подписанное продвижение с обеих сторон - но почему?
Оба исполняемых файла скомпилированы как 64-битные, это может сыграть свою роль?
1 ответ
Там нет отрицательных целочисленных констант. Есть только положительные с одинарным -
оператор применяется.
поскольку 2147483648 > INT_MAX
, что способствует 2147483648
к следующему большему подписанному (потому что вы не добавили u
) целочисленный тип, перед -
применены.
Кстати, вот почему INT_MIN
обычно определяется как (-INT_MAX - 1)
в <limits.h>
,;-)