¿Cuál es la diferencia entre int firmado y sin firmar?
¿Cuál es la diferencia entre int firmado y sin firmar?
Respuestas:
Como probablemente sepa, los correos int
electrónicos se almacenan internamente en binario. Normalmente, una int
contiene 32 bits, pero en algunos entornos puede contener 16 o 64 bits (o incluso un número diferente, por lo general, pero no necesariamente una potencia de dos).
Pero para este ejemplo, veamos enteros de 4 bits. Diminuto, pero útil con fines ilustrativos.
Como hay cuatro bits en dicho número entero, puede asumir uno de 16 valores; 16 es dos elevado a la cuarta potencia, o 2 por 2 por 2 por 2. ¿Cuáles son esos valores? La respuesta depende de si este entero es un signed int
o un unsigned int
. Con an unsigned int
, el valor nunca es negativo; no hay ningún signo asociado con el valor. Aquí están los 16 valores posibles de un cuatro bits unsigned int
:
bits value
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 8
1001 9
1010 10
1011 11
1100 12
1101 13
1110 14
1111 15
... y aquí están los 16 valores posibles de un cuatro bits signed int
:
bits value
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 -8
1001 -7
1010 -6
1011 -5
1100 -4
1101 -3
1110 -2
1111 -1
Como puede ver, para signed int
s el bit más significativo es 1
si y solo si el número es negativo. Por eso, para signed int
s, este bit se conoce como "bit de signo".
(unsigned)(-1)
se requiere que sea el valor máximo representable para unsigned
(independiente de la representación binaria), lo cual es trivialmente cierto para el complemento a dos, pero no para otras representaciones.
int
y unsigned int
son dos tipos de enteros distintos. ( int
también puede denominarse signed int
, o simplemente signed
; unsigned int
también puede denominarse unsigned
.)
Como los nombres implican, int
es un firmado tipo entero, y unsigned int
es un unsigned tipo entero. Eso significa que int
puede representar valores negativos y unsigned int
solo puede representar valores no negativos.
El lenguaje C impone algunos requisitos a los rangos de estos tipos. La gama de int
debe ser al menos -32767
.. +32767
, y la gama de unsigned int
debe ser al menos 0
.. 65535
. Esto implica que ambos tipos deben tener al menos 16 bits. Son de 32 bits en muchos sistemas, o incluso de 64 bits en algunos. int
normalmente tiene un valor negativo adicional debido a la representación en complemento a dos utilizada por la mayoría de los sistemas modernos.
Quizás la diferencia más importante es el comportamiento de la aritmética con signo y sin signo. Para firmado int
, el desbordamiento tiene un comportamiento indefinido. Porque unsigned int
no hay desbordamiento; cualquier operación que arroje un valor fuera del rango del tipo se envuelve, por ejemplo UINT_MAX + 1U == 0U
.
Cualquier tipo de entero, con o sin signo, modela un subrango del conjunto infinito de enteros matemáticos. Siempre que trabaje con valores dentro del rango de un tipo, todo funciona. Cuando se acerca al límite inferior o superior de un tipo, encuentra una discontinuidad y puede obtener resultados inesperados. Para los tipos enteros con signo, los problemas ocurren solo para valores muy grandes negativos y positivos, que exceden INT_MIN
y INT_MAX
. Para los tipos enteros sin signo, se producen problemas para valores positivos muy grandes y en cero . Esto puede ser una fuente de errores. Por ejemplo, este es un bucle infinito:
for (unsigned int i = 10; i >= 0; i --) [
printf("%u\n", i);
}
porque siemprei
es mayor o igual a cero; esa es la naturaleza de los tipos sin firmar. (Dentro del ciclo, cuando es cero, establece su valor en ).i
i--
UINT_MAX
A veces sabemos de antemano que el valor almacenado en una variable entera dada siempre será positivo, cuando se usa solo para contar cosas, por ejemplo. En tal caso se puede declarar la variable no está firmado, como en, unsigned int num student;
. Con tal declaración, el rango de valores enteros permitidos (para un compilador de 32 bits) cambiará del rango -2147483648 a +2147483647 al rango 0 a 4294967295. Por lo tanto, declarar un entero como sin signo casi duplica el tamaño del mayor posible valor que de otro modo puede tener.
En términos sencillos, un int sin signo es un número entero que no puede ser negativo y, por lo tanto, tiene un rango más alto de valores positivos que puede asumir. Un int con signo es un número entero que puede ser negativo pero tiene un rango positivo más bajo a cambio de valores más negativos que puede asumir.
En la práctica, existen dos diferencias:
cout
en C ++ o printf
en C): la representación de bits enteros sin signo se interpreta como un entero no negativo por las funciones de impresión.este código puede identificar el número entero usando el criterio de orden:
char a = 0;
a--;
if (0 < a)
printf("unsigned");
else
printf("signed");