Почему отрицательный int больше, чем unsigned int?
int main(void)
{
unsigned int y = 10;
int x = – 4;
if (x > y)
Printf("x is greater");
else
Printf("y is greater");
getch();
return (0);
}
Output: x is greater
Я думал, что выход будет y больше, потому что он без знака. В чем причина этого?
Ответы
Ответ 1
Поскольку значение int
повышается до unsigned int
. в частности 0xFFFFFFFC
на 32-битной машине, которая как unsigned int
равна 4294967292
, значительно больше, чем 10
C99 6.3.1.1-p2
Если int может представлять все значения исходного типа (ограниченные шириной для битового поля), значение преобразуется в int; в противном случае он преобразуется в unsigned int. Они называются целыми акциями. Все остальные типы не изменяются целыми рекламными акциями.
Чтобы выполнить преобразование:
C99 6.3.1.3-p2
В противном случае, если новый тип без знака, значение преобразуется путем многократного добавления или вычитания более чем максимального значения, которое может быть представлено в новом типе, пока значение не будет в диапазоне нового типа.
Что в основном означает "добавить UINT_MAX + 1" (как я его прочитал, так или иначе).
Относительно того, почему акция была направлена на сторону unsigned int
; Приоритет:
C99 6.3.1.8-p1
... В противном случае, если операнд с целым типом без знака имеет ранг, больший или равный рану типа другого операнда, то операнд со знаком целочисленного типа преобразуется в тип операнда с целым числом без знака тип.
В противном случае, если тип операнда со знаком целочисленного типа может представлять все значения типа операнда с целым целым числом без знака, то операнд с целым типом без знака преобразуется в тип операнда со знаком целого числа тип.
Что говорит мне, что int
vs. unsigned char
должно работать как ожидалось.
Test
int main()
{
int x = -4;
unsigned int y = 10;
unsigned char z = 10;
if (x > y)
printf("x>y\n");
else
printf("x<y\n");
if (x > z)
printf("x>z\n");
else
printf("x<z\n");
return 0;
}
Выход
x>y
x<z
Хорошо посмотри на это.
Ответ 2
Сравнение между подписанным и неподписанным значением будет сделано в "unsigned space". I.e., подписанное значение будет преобразовано в unsigned, добавив UINT_MAX + 1
. В реализации с использованием 2-дополнения для отрицательных значений не требуется специальной обработки значений под капотом.
В этом примере -4
превращается в 0x100000000-4
= 0xFFFFFFFC
, который явно > 10
.
Ответ 3
Когда вы сравниваете два значения в C, они оба должны быть одного типа. В этом случае (int
и unsigned int
) значение int
будет сначала преобразовано в unsigned int
.
Во-вторых, целочисленная арифметика без знака в C выполняется по модулю максимального значения этого типа + 1 (т.е. оно "обходит вокруг", поэтому UINT_MAX + 1
снова 0
и наоборот). Поэтому преобразование отрицательных значений в неподписанные результаты в очень больших количествах.
В соответствующем разделе стандарта говорится:
6.3.1.3 Целочисленные и беззнаковые целые числа
2
В противном случае, если новый тип без знака, значение преобразуется путем повторного добавления или вычитая одно больше максимального значения, которое может быть представлено в новом типе пока значение не будет в диапазоне нового типа.
Ответ 4
При сравнении int
и unsigned int
int
преобразуется в unsigned int
.
Преобразование int
в unsigned int
выполняется добавлением UINT_MAX+1
(обратите внимание, что ваш int
отрицательный). Так что вы сравниваете:
if (-3 + UINT_MAX > 10) //Since -4 is converted to UINT_MAX+1-4
Это правда.
Ответ 5
Первый бит значения int используется для определения положительной или отрицательной. (1 = отрицательный, 0 положительный)
Ваша обе переменная передается в unsigned int перед сравнением, где 1 в первом бите будет интерпретироваться как часть вашего номера.
этот код должен работать нормально:
int main(void)
{
unsigned int y = 10;
int x = – 4;
if (x > (int) y)
Printf("x is greater");
else
Printf ("y is greater");
getch ( );
return (0);
}
Ответ 6
int x = -4 (2 дополнение к 4 равно 1111 1100 = 252), а unsigned int y = 10 (0000 1010 = 10), поэтому 252 > 10, так что -4 больше 10.