¿Por qué es un int negativo mayor que unsigned int? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

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

Pensé que la salida sería y es mayor ya que no tiene signo. ¿Cuál es la razón detrás de esto?

Author: OcuS, 2012-11-28

6 answers

Porque el valor int se promueve a un unsigned int. específicamente 0xFFFFFFFC en una máquina de 32 bits, que como unsigned int es 4294967292, considerablemente mayor que 10

C99 6.3.1.1-p2

Si un int puede representar todos los valores del tipo original (como restringido por el ancho, para un campo de bits), el valor se convierte en un int; de lo contrario, se convierte en un int sin signo. Estos se llaman las promociones de enteros. Todos los otros tipos son sin cambios por el promociones de enteros.

Para realizar la conversión:

C99 6.3.1.3-p2

De lo contrario, si el nuevo tipo no está firmado, el valor se convierte agregando o restando repetidamente uno más que el valor máximo que se puede representar en el nuevo tipo hasta que el valor esté en el rango del nuevo tipo.

Que básicamente significa "agregar UINT_MAX+1" (como lo leí, de todos modos).

Con respecto a por qué la promoción fue para el lado unsigned int; precedencia:

C99 6.3.1.8-p1

...De lo contrario, si el operando que tiene un tipo entero sin signo tiene un rango mayor o igual al rango del tipo del otro operando, entonces el operando con tipo entero con signo se convierte al tipo del operando con tipo entero sin signo.

De lo contrario, si el tipo del operando con tipo entero con signo puede representar todos los valores del tipo del operando con tipo entero sin signo, entonces el el operando con tipo entero sin signo se convierte al tipo del operando con tipo entero con signo.

Que me dice int vs unsigned char debería funcionar como se esperaba.

Prueba

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;
}

Salida

x>y
x<z

Bueno, mira eso.

 44
Author: WhozCraig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-27 12:56:49

Se realizará una comparación entre un valor con signo y un valor sin signo en "espacio sin signo". Es decir, el valor con signo se convertirá a sin signo añadiendo UINT_MAX + 1. En la implementación utilizando el complemento 2 para valores negativos, no se requiere un manejo especial de los valores debajo del capó.

En este ejemplo, el -4 se convierte en un 0x100000000-4 = 0xFFFFFFFC que es claramente > 10.

 11
Author: glglgl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-28 09:02:36

Cuando se comparan dos valores en C, ambos deben ser del mismo tipo. En este caso (int y unsigned int) el valor int se convertirá en un unsigned int primero.

En segundo lugar, la aritmética de enteros sin signo en C se realiza módulo el valor máximo de ese tipo + 1 (es decir, "gira alrededor" por lo que UINT_MAX + 1 es 0 de nuevo y viceversa). Por lo tanto, convertir valores negativos a sin signo resulta en números muy grandes.

La sección relevante en el estándar dice:

6.3.1.3 Enteros firmados y sin firmar

2
De lo contrario, si el nuevo tipo no está firmado, el valor se convierte añadiendo o restando uno más que el valor máximo que se puede representar en el nuevo tipo hasta que el valor esté en el rango del nuevo tipo.

 4
Author: melpomene,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-28 08:52:56

Cuando comparas un int y un unsigned int el int se convierte en unsigned int. La conversión de un int a un unsigned int se realiza agregando UINT_MAX+1 (tenga en cuenta que su int es negativo). Así que en realidad usted está comparando:

if (-3 + UINT_MAX > 10)  //Since -4 is converted to UINT_MAX+1-4

Que es verdad.

 3
Author: Maroun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-28 08:54:37

El primer bit de un valor int se usa para definir si es positivo o negativo. (1 = negativo, 0 positivo) Ambas variables se convierten en int sin signo antes de la comparación donde el 1 en el primer bit se interpretará como parte de su número.

Este código debería funcionar bien:

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); 

 } 
 1
Author: Jeremie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-28 08:47:36

Int x=-4 (complemento de 4 de 2 es 1111 1100 =252) y int y=10 sin signo es(0000 1010 =10) so 252 >10 so -4 es mayor que 10.

 -2
Author: suren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-28 08:54:05