Почему отрицательный 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 больше, так как он без знака. В чем причина этого?

6 ответов


потому что int значение повышается до unsigned int. в частности,0xFFFFFFFC на 32-битной машине, которая как unsigned int is 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

...В противном случае, если операнд с целочисленным типом без знака имеет ранг, больший или равный рангу типа другого операнда, то операнд со знаком целочисленного типа преобразуется в тип операнда с целочисленным типом без знака.

в противном случае, если тип операнда со знаком integer type может представлять все значения типа операнда с беззнаковым целочисленным типом, затем операнд с беззнаковым целочисленным типом преобразуется в тип операнда со знаком integer type.

что говорит мне int и unsigned char должны работать, как ожидалось.

тест

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

ну посмотрите на это.


сравнение между подписанным и неподписанным значением будет выполнено в "unsigned space". То есть, подписанное значение будет преобразовано в unsigned путем добавления UINT_MAX + 1. При реализации с использованием 2-комплемента для отрицательных значений специальная обработка значений под капотом не требуется.

в этом примере -4 превращается в 0x100000000-4 = 0xFFFFFFFC что явно > 10.


когда вы сравниваете два значения в C, они оба должны быть одного типа. В этом случае (int и unsigned int) в int значение будет преобразовано в unsigned int первый.

во-вторых, беззнаковая целочисленная арифметика В C выполняется по модулю максимального значения этого типа + 1 (то есть она "петляет" так UINT_MAX + 1 is 0 снова и наоборот). Поэтому преобразование отрицательных значений в неподписанные результаты в очень больших числах.

соответствующий раздел стандарта говорит:

6.3.1.3 целые числа со знаком и без знака

2
В противном случае, если новый тип без знака, значение преобразуется путем многократного сложения или вычитание на одно больше максимального значения, которое может быть представлено в новом типе до тех пор, пока значение находится в диапазоне нового типа.


при сравнении 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

это правда.


Первый БИТ значения 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); 

 } 

int x=-4 (дополнение 2 к 4 равно 1111 1100 =252) и unsigned int y=10 равно(0000 1010 =10), поэтому 252 >10 so -4 больше 10.