¿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?
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.
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
.
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.
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.
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);
}
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.
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