2010-05-11 27 views
8

Lo que sé de los valores numéricos sin signo (unsigned short, int y largos), que contiene los números positivos solamente, pero el siguiente programa sencillo asignado correctamente un número negativo a un unsigned int:int Por qué no firmada contenía número negativo

1 /* 
    2 * ===================================================================================== 
    3 * 
    4 *  Filename: prog4.c 
    5 * 
    6 * ===================================================================================== 
    7 */ 
    8 
    9 #include <stdio.h> 
10 
11 int main(void){ 
12 
13  int v1 =0, v2=0; 
14  unsigned int sum; 
15  
16  v1 = 10; 
17  v2 = 20; 
18  
19  sum = v1 - v2; 
20  
21  printf("The subtraction of %i from %i is %i \n" , v1, v2, sum); 
22  
23  return 0; 
24 } 

la salida es: The subtraction of 10 from 20 is -10

+4

Además, su mensaje es engañoso. Debería decir "La resta de ** 20 ** de ** 10 ** es ..." que es lo que está calculando. –

+0

No estoy buscando una solución para ese problema, quiero entender la idea al respecto. –

+0

Posible duplicado de [C Unsigned int que proporciona un valor negativo?] (Http://stackoverflow.com/questions/1831753/c-unsuns-int-providing-a-negative-value) –

Respuesta

22

%i es el especificador de formato para un firmado número entero; necesita usar %u para imprimir un entero sin signo.

+2

Recuerde, porque los valores sin firmar solo pueden almacenar valores no negativos, al restar un entero sin signo de otro resultará en un subdesbordamiento si el minuendo es más pequeño que el sustraendo, entonces obtendrás un subdesbordamiento. Eche un vistazo: http://www.topbits.com/integer-overflow.html – LandonSchropp

1

Puesto que el valor entero sin signo que se almacena en suma es tratado como entero decimal firmado en printf %i

8

Con printf, el formato de salida a una %isigned int. Use %u para generar un unsigned int. Este es un problema común al comenzar la programación en C. Para responder a su pregunta, el resultado de v1 - v2 es -10, pero sum es unsigned int, por lo que la respuesta real es probablemente algo así como 4294967286 (2 - 10). Vea lo que obtiene cuando usa The subtraction of %i from %i is %u \n. :)

6

Firmado int y unsigned int tienen el mismo tamaño en la memoria, la única diferencia entre ellos es cómo los interpretas. Los valores firmados usan una representación de complemento a dos.

Si pone 0xFFFFFFFF en una ubicación de memoria de 4 bytes, y luego pregunta cuál es el valor allí? Bueno, si lo interpretamos como un int firmado, entonces es -1, pero si lo interpretamos como un int no firmado, entonces el valor es 4294967295. De cualquier manera es el mismo patrón de bit, la diferencia es qué significado le damos.

Cuando asignó 10 - 20 en un int sin firmar, calculó un valor de -10 (C no hace overflow o comprobación de subdesbordamiento), que es un patrón de bit de 0xFFFFFFF6, lo que significa -10 en un int firmado o 4294967286 en unsigned int. Si luego le dice al compilador (usando% i) que imprima un int firmado, entonces interpreta ese patrón de bits como un int firmado e imprime -10, si le dijo al compilador (usando% u) que imprima un int sin firmar, entonces interpreta ese patrón de bits como sin firmar e imprime 4294967286.

+0

Entonces, la forma en que interpreto el patrón de bits controla el valor en la memoria. Gracias. –

+0

Bueno, el valor "en memoria" es siempre el mismo. Ellos son los mismos bits. Lo que cambia es la forma en que se produce. – Veky

Cuestiones relacionadas