¿Es correcto decir que la diferencia entre un entero con signo y sin signo es:
- Sin signo puede contener un valor positivo mayor y ningún valor negativo.
- Unsigned usa el bit inicial como parte del valor, mientras que la versión firmada usa el bit más a la izquierda para identificar si el número es positivo o negativo.
- los enteros con signo pueden contener números positivos y negativos.
¿Alguna otra diferencia?
language-agnostic
integer
unsigned
signed
Shimmy Weitzhandler
fuente
fuente
Respuestas:
Si.
Hay diferentes formas de representar enteros con signo. Lo más fácil de visualizar es usar el bit más a la izquierda como bandera ( signo y magnitud ), pero lo más común es el complemento a dos . Ambos están en uso en la mayoría de los microprocesadores modernos: el punto flotante usa signos y magnitud, mientras que la aritmética entera usa el complemento de dos.
si
fuente
Entraré en diferencias a nivel de hardware, en x86. Esto es principalmente irrelevante a menos que esté escribiendo un compilador o utilizando lenguaje ensamblador. Pero es bueno saberlo.
En primer lugar, x86 tiene soporte nativo para la representación complementaria de dos números con signo. Puede usar otras representaciones, pero esto requeriría más instrucciones y, en general, sería una pérdida de tiempo del procesador.
¿Qué quiero decir con "soporte nativo"? Básicamente quiero decir que hay un conjunto de instrucciones que usa para números sin signo y otro conjunto que usa para números con signo. Los números sin signo pueden ubicarse en los mismos registros que los números con signo, y de hecho puede mezclar instrucciones con y sin signo sin preocuparse por el procesador. Depende del compilador (o programador de ensamblaje) hacer un seguimiento de si un número está firmado o no, y usar las instrucciones apropiadas.
En primer lugar, los números del complemento a dos tienen la propiedad de que la suma y la resta son exactamente las mismas que para los números sin signo. No importa si los números son positivos o negativos. (Así que simplemente sigue adelante
ADD
ySUB
tus números sin preocuparte).Las diferencias comienzan a mostrarse cuando se trata de comparaciones. x86 tiene una manera simple de diferenciarlos: arriba / abajo indica una comparación sin signo y mayor / menor que indica una comparación con signo. (Por ejemplo,
JAE
significa "Saltar si es superior o igual" y no está firmado).También hay dos conjuntos de instrucciones de multiplicación y división para tratar con enteros con y sin signo.
Por último: si desea verificar, por ejemplo, desbordamiento, lo haría de manera diferente para los números con y sin signo.
fuente
Solo preguntó sobre firmado y no firmado. No sé por qué la gente está agregando cosas adicionales en esto. Déjame decirte la respuesta.
Sin signo: consta solo de valores no negativos, es decir, de 0 a 255.
Firmado: consta de valores negativos y positivos, pero en diferentes formatos como
Y esta explicación es sobre el sistema de números de 8 bits.
fuente
Solo algunos puntos para completar:
esta respuesta está discutiendo solo representaciones enteras. Puede haber otras respuestas para coma flotante;
La representación de un número negativo puede variar. El más común (de lejos, hoy es casi universal) en uso hoy es el complemento de dos . Otras representaciones incluyen el complemento de uno (bastante raro) y la magnitud con signo (muy poco común, probablemente solo se usa en piezas de museo) que simplemente usa el bit alto como un indicador de signo con los bits restantes que representan el valor absoluto del número.
Cuando se usa el complemento a dos, la variable puede representar un rango mayor (por uno) de números negativos que números positivos. Esto se debe a que el cero está incluido en los números 'positivos' (ya que el bit de signo no está configurado para cero), pero no los números negativos. Esto significa que el valor absoluto del número negativo más pequeño no se puede representar.
cuando se usa el complemento de uno o la magnitud con signo, puede tener cero representado como un número positivo o negativo (que es una de las dos razones por las que estas representaciones no se usan normalmente).
fuente
De acuerdo con lo que aprendimos en clase, los enteros con signo pueden representar números positivos y negativos, mientras que los enteros sin signo solo no son negativos.
Por ejemplo, mirando un número de 8 bits :
valores sin signo
0
a255
los valores con signo varían de
-128
a127
fuente
Todo excepto el punto 2 es correcto. Hay muchas notaciones diferentes para las entradas firmadas, algunas implementaciones usan la primera, otras usan la última y otras usan algo completamente diferente. Todo depende de la plataforma con la que esté trabajando.
fuente
Otra diferencia es cuando estás convirtiendo enteros de diferentes tamaños.
Por ejemplo, si está extrayendo un número entero de una secuencia de bytes (digamos 16 bits por simplicidad), con valores sin signo, podría hacer:
(probablemente debería emitir el 2 nd bytes, pero supongo que el compilador hará lo correcto)
Con los valores firmados, debería preocuparse por la extensión del signo y hacer:
fuente
En general, eso es correcto. Sin saber nada más acerca de por qué está buscando las diferencias, no puedo pensar en ningún otro diferenciador entre firmado y no firmado.
fuente
Más allá de lo que otros han dicho, en C, no se puede desbordar un entero sin signo; El comportamiento se define como módulo aritmético. Puede desbordar un entero con signo y, en teoría (aunque no en la práctica en los sistemas convencionales actuales), el desbordamiento podría desencadenar una falla (quizás similar a una falla dividida por cero).
fuente
fuente
(en respuesta a la segunda pregunta) Al usar solo un bit de signo (y no el complemento de 2), puede terminar con -0. No muy bonita
fuente
Los enteros con signo en C representan números. Si
a
yb
son variables de tipos enteros con signo, el estándar nunca requerirá que un compilador haga que la expresión sea+=b
almacene ena
otra cosa que no sea la suma aritmética de sus valores respectivos. Para estar seguros, si la suma aritmética no encajaa
, el procesador podría no ser capaz de colocarla allí, pero el estándar no requeriría que el compilador truncara o ajustara el valor, o hiciera cualquier otra cosa si los valores exceden Los límites para sus tipos. Tenga en cuenta que si bien el estándar no lo requiere, las implementaciones de C pueden atrapar desbordamientos aritméticos con valores firmados.Los enteros sin signo en C se comportan como anillos algebraicos abstractos de enteros que son módulos congruentes con una potencia de dos, excepto en escenarios que involucran conversiones u operaciones con tipos más grandes. La conversión de un número entero de cualquier tamaño a un tipo sin signo de 32 bits producirá el miembro correspondiente a cosas que son congruentes con ese número entero mod 4.294.967.296. La razón por la que restar 3 de 2 produce 4,294,967,295 es que agregar algo congruente a 3 a algo congruente a 4,294,967,295 producirá algo congruente a 2.
Los tipos abstractos de anillos algebraicos son a menudo cosas útiles para tener; desafortunadamente, C usa la firma como factor decisivo para determinar si un tipo debe comportarse como un anillo. Peor aún, los valores sin signo se tratan como números en lugar de miembros del anillo cuando se convierten a tipos más grandes, y los valores sin signo más pequeños que
int
se convierten a números cuando se realiza una aritmética sobre ellos. Siv
es unuint32_t
igual4,294,967,294
, entoncesv*=v;
debería hacerv=4
. Desafortunadamente, siint
son 64 bits, entonces no se sabe quév*=v;
podría hacer.Dado el estándar tal como es, sugeriría usar tipos sin signo en situaciones en las que uno quiera el comportamiento asociado con los anillos algebraicos, y los tipos con signo cuando quiera representar números. Es lamentable que C hiciera las distinciones de la manera en que lo hizo, pero son lo que son.
fuente
Los enteros sin signo son mucho más propensos a atraparte en una trampa particular que los enteros con signo. La trampa proviene del hecho de que, si bien los puntos 1 y 3 anteriores son correctos, a ambos tipos de enteros se les puede asignar un valor fuera de los límites de lo que puede "retener" y se convertirá en silencio.
Cuando ejecute esto, obtendrá el siguiente resultado a pesar de que ambos valores se asignaron a -1 y se declararon de manera diferente.
fuente
La única diferencia garantizada entre un valor con signo y uno sin signo en C es que el valor con signo puede ser negativo, 0 o positivo, mientras que un sin signo solo puede ser 0 o positivo. El problema es que C no define el formato de los tipos (por lo que no sabe que sus enteros están en el complemento de dos). Estrictamente hablando, los dos primeros puntos que mencionó son incorrectos.
fuente
Debe usar enteros sin signo al programar en sistemas integrados. En los bucles, cuando no se necesitan enteros con signo, el uso de enteros sin signo ahorrará la seguridad necesaria para diseñar dichos sistemas.
fuente