Moumita Das
¿Cuál es la diferencia entre int firmado y sin firmar?
Bill Evans en Mariposa
Como probablemente sepa, int
Los correos electrónicos se almacenan internamente en binario. Típicamente un 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 los enteros de 4 bits. Pequeño, pero útil para fines ilustrativos.
Dado que hay cuatro bits en dicho entero, puede asumir uno de los 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 un unsigned int
, el valor nunca es negativo; no hay 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 puedes ver, por signed int
s el bit más significativo es 1
si y solo si el número es negativo. Por eso, por signed int
s, este bit se conoce como “bit de signo”.
-
Tal vez valga la pena señalar que este es el formato de complemento a dos, que sin duda es ampliamente utilizado en la actualidad. También hay otras formas de representar enteros con signo, sobre todo el complemento de uno.
– Schedler
26 de abril de 2011 a las 11:59
-
Correcto. Y el estándar ISO9899 C ni siquiera requiere que se use el complemento a uno o el complemento a dos; cualquier otra convención que realmente funcione es permisible.
– Bill Evans en Mariposa
26 de abril de 2011 a las 15:31
-
Aunque no se requiere el complemento a dos,
(unsigned)(-1)
se requiere que sea el valor máximo representable paraunsigned
(independiente de la representación binaria), lo cual es trivialmente cierto para el complemento a 2, pero no para otras representaciones.– rubenvb
23 de noviembre de 2011 a las 11:52
-
@BillEvansatMariposa: El estándar dice que para los enteros con signo hay 3 representaciones permitidas: signo+magnitud, complemento a 2, complemento a 1. Cualquier otro tendría que ser invisible para el programa y ser percibido como uno de estos 3.
– Alexei Frunze
23 de noviembre de 2011 a las 11:57
-
Ok, pero bajo el capó! ¡Qué está pasando REALMENTE! ¡Cuál es la diferencia entre un número FIRMADO y NO FIRMADO! ¿Cómo gestiona la máquina el cálculo? ¿Simplemente resta un valor del otro? ¿Cómo se diferencia 1111 = 15 y 1111 = -1?
– Mihail Georgescu
18 de marzo de 2016 a las 14:22
En términos simples, 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.
-
A veces, respuestas simples como esta ayudan mucho a explicar esto.
– nishchalpro
5 de febrero de 2021 a las 2:05
keith thompson
int
y unsigned int
son dos tipos enteros distintos. (int
también puede ser referido como signed int
o solo signed
; unsigned int
también puede ser referido como unsigned
.)
Como los nombres implican, int
es un firmado tipo entero, y unsigned int
es un no firmado tipo entero. Eso significa que int
es capaz de representar valores negativos, y unsigned int
sólo puede representar valores no negativos.
El lenguaje C impone algunos requisitos sobre los rangos de estos tipos. El rango de int
debe ser por lo menos -32767
.. +32767
y el rango de unsigned int
debe ser por lo 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 de 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 frente a la sin signo. para firmado int
, el desbordamiento tiene un comportamiento indefinido. Para unsigned int
, no hay desbordamiento; cualquier operación que produzca un valor fuera del rango del tipo se reinicia, por ejemplo UINT_MAX + 1U == 0U
.
Cualquier tipo de entero, con o sin signo, modela un subrango del conjunto infinito de enteros matemáticos. Mientras 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 negativos y positivos muy grandes, que exceden INT_MIN
y INT_MAX
. Para tipos enteros sin signo, los problemas ocurren para valores positivos muy grandes y en cero. Esto puede ser una fuente de errores. Por ejemplo, este es un bucle infinito:
para (int sin signo i = 10; i >= 0; i --) [
printf("%u\n", i);
}
because i
is always greater than or equal to zero; that’s the nature of unsigned types. (Inside the loop, when i
is zero, i--
sets its value to UINT_MAX
.)
imran
Sometimes we know in advance that the value stored in a given integer variable will always be positive-when it is being used to only count things, for example. In such a case we can declare the variable to be unsigned, as in, unsigned int num student;
. With such a declaration, the range of permissible integer values (for a 32-bit compiler) will shift from the range -2147483648 to +2147483647 to range 0 to 4294967295. Thus, declaring an integer as unsigned almost doubles the size of the largest possible value that it can otherwise hold.
Minimus Heximus
In practice, there are two differences:
- printing (eg with
cout
in C++ orprintf
in C): unsigned integer bit representation is interpreted as a nonnegative integer by print functions. - ordering: the ordering depends on signed or unsigned specifications.
this code can identify the integer using ordering criterion:
char a = 0;
a--;
if (0 < a)
printf("unsigned");
else
printf("signed");
char
is considered signed
in some compilers and unsigned
in other compilers. The code above determines which one is considered in a compiler, using the ordering criterion. If a
is unsigned, after a--
, it will be greater than 0
, but if it is signed
it will be less than zero. But in both cases, the bit representation of a
is the same. That is, in both cases a--
does the same change to the bit representation.
-
If this explained the different with one dealing in negative numbers and the other, not. It would help this post a lot.
– Daniel JacksonNov 18, 2019 at 15:41
-
@DanielJackson Unclear what you say. a char can be considered negative or positive depending on compiler. the output of the code depends on what compiler chooses and this shows the difference between signed and unsigned.
– Minimus HeximusNov 23, 2019 at 16:27
-
If this explained the different with one dealing in negative numbers and the other, not. It would help this post a lot.
– Daniel JacksonNov 18, 2019 at 15:41
-
@DanielJackson Unclear what you say. a char can be considered negative or positive depending on compiler. the output of the code depends on what compiler chooses and this shows the difference between signed and unsigned.
– Minimus HeximusNov 23, 2019 at 16:27
Esta es una pregunta real, y la respuesta no es tan simple sino más bien sutil.
– R.. GitHub DEJA DE AYUDAR A ICE
21 de abril de 2011 a las 5:36
Votación para reabrir. Puede ser un duplicado, pero definitivamente es una pregunta real.
– Brian
21 de abril de 2011 a las 13:27
Re: “Podría ser un duplicado” – ¿Cuál es la diferencia entre un int sin firmar y un int con firma en C?
– eldarerathis
21 de abril de 2011 a las 21:27
Se deben agregar más etiquetas, ya que muchos idiomas las usan.
– Juan Boero
19 de junio de 2015 a las 14:02
Esta pregunta puede necesitar un capítulo para ser elaborada. Si quieres conocer los entresijos, consulta Enteros con y sin signo para más explicación.
– anónimo
30 de mayo de 2017 a las 2:20