signo representacion numeros numero negativos menos magnitud complemento como calcula binarios binario binary math twos-complement negative-number internal-representation

binary - negativos - representacion de numeros binarios



¿Por qué preferir el complemento de dos a la magnitud y al signo de los números con signo? (17)

Aunque esta pregunta es antigua, permítanme poner mis 2 centavos.

Antes de explicar esto, volvamos a lo básico. El complemento 2 ''es complemento de 1 + 1. Ahora, ¿cuál es el complemento de 1 y cuál es su significado, además?

La suma de cualquier número de n bits y su complemento de 1 le da el número más alto posible que se puede representar con esos n bits. Ejemplo:

0010 (2 in 4 bit system) +1101 (1''s complement of 2) ___________________________ 1111 (the highest number that we can represent by 4 bits)

Ahora, ¿qué pasará si tratamos de agregar 1 más al resultado? Se producirá un desbordamiento.

El resultado será 1 0000 que es 0 (ya que estamos trabajando con números de 4 bits, (el 1 de la izquierda es un desbordamiento)

Asi que ,

Any n-bit number + its 1''s complement = max n-bit number Any n-bit number + its 1''complement + 1 = 0 ( as explained above, overflow will occur as we are adding 1 to max n-bit number)

Alguien luego decidió llamar complemento de 1 + 1 como complemento de 2. Entonces la afirmación anterior se convierte en: Cualquier número nbit + su complemento 2 = 0 lo que significa complemento 2 de un número = - (de ese número)

Todo esto arroja una pregunta más, ¿por qué solo podemos usar el (n-1) de los n bits para representar el número positivo y por qué el bit más a la izquierda representa el signo (0 en el bit más a la izquierda significa número + ve, y 1 significa -ve número). por ejemplo, ¿por qué usamos solo los primeros 31 bits de un int en java para representar un número positivo si el 32º bit es 1, es un número -ve.

1100 (lets assume 12 in 4 bit system) +0100(2''s complement of 12) ___________________________

1 0000 (el resultado es cero, con el acarreo 1 desbordado)

Por lo tanto, el sistema de (n + 2''complemento de n) = 0, todavía funciona. La única ambigüedad aquí es el complemento de 2 de 12 es 0100 que también representa ambiguamente +8, además de representar -12 en el sistema complementario de 2s.

Este problema se resolverá si los números positivos siempre tienen un 0 en su bit más a la izquierda. En ese caso, su complemento 2 siempre tendrá un 1 en su bit más a la izquierda, y no tendremos la ambigüedad del mismo conjunto de bits que representa un número de complemento de 2, así como un número + ve.

Solo tengo curiosidad si hay una razón por la cual para representar -1 en binario, se usa el complemento de dos: voltear los bits y agregar 1?

-1 está representado por 11111111 (complemento de dos) en lugar de (para mí más intuitivo) 10000001 que es binario 1 con el primer bit como indicador negativo.

Descargo de responsabilidad: ¡No confío en la aritmética binaria para mi trabajo!


Bueno, tu intención no es realmente revertir todos los bits de tu número binario. En realidad, es restar cada dígito de 1. Es solo una coincidencia afortunada que restar 1 de 1 resulta en 0 y restar 0 de 1 resultados en 1. Así que invertir bits está llevando a cabo efectivamente esta resta.

¿Pero por qué estás encontrando la diferencia de cada dígito de 1? Bueno, no lo eres. Su intención real es calcular la diferencia del número binario dado de otro número binario que tiene el mismo número de dígitos pero contiene solo 1. Por ejemplo, si su número es 10110001, cuando invierte todos esos bits, estará efectivamente informándose (11111111 - 10110001).

Esto explica el primer paso en el cálculo del Complemento de Dos. Ahora vamos a incluir el segundo paso, agregar 1, también en la imagen.

Agrega 1 a la ecuación binaria anterior:

11111111 - 10110001 + 1

¿Qué obtienes? Esta:

100000000 - 10110001

Esta es la ecuación final. Y al llevar a cabo esos dos pasos, está tratando de encontrar esto, diferencia final: el número binario restado de otro número binario con un dígito adicional y que contiene ceros, excepto en la posición del bit de mayor significancia.

Pero, ¿por qué anhelamos esta diferencia realmente? Bueno, a partir de ahora, supongo que sería mejor si lees el Wikipedia .


El complemento a dos permite agregar números negativos y positivos sin ninguna lógica especial.

Si trataste de agregar 1 y -1 usando tu método
10000001 (-1)
+00000001 (1)
usted obtiene
10000010 (-2)

En cambio, al usar el complemento de dos, podemos agregar

11111111 (-1)
+00000001 (1) obtienes
00000000 (0)

Lo mismo es cierto para la resta.

Además, si tratas de restar 4 de 6 (dos números positivos) puedes complementar 2 y agregar los dos juntos 6 + (-4) = 6 - 4 = 2

Esto significa que la resta y la suma de los números positivos y negativos se pueden hacer por el mismo circuito en la CPU.


La implementación habitual de la operación es "voltear los bits y agregar 1", pero hay otra forma de definirlo que probablemente aclare la lógica. El complemento de 2 es la forma que obtienes si tomas la representación normal sin signo donde cada bit controla la siguiente potencia de 2, y simplemente haces que el término más significativo sea negativo.

Tomando un valor de 8 bits a 7 a 6 a 5 a 4 a 3 a 2 a 1 a 0

La interpretación binaria sin signo habitual es:
2 7 * a 7 + 2 6 * a 6 + 2 5 * a 5 + 2 4 * a 4 + 2 3 * a 3 + 2 2 * a 2 + 2 1 * a 1 + 2 0 * a 0
11111111 = 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255

La interpretación del complemento a dos es:
-2 7 * a 7 + 2 6 * a 6 + 2 5 * a 5 + 2 4 * a 4 + 2 3 * a 3 + 2 2 * a 2 + 2 1 * a 1 + 2 0 * a 0
11111111 = -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = -1

Ninguno de los otros bits cambia el significado en absoluto, y llevar a un 7 es "desbordamiento" y no se espera que funcione, así que casi todas las operaciones aritméticas funcionan sin modificación (como otros han notado). La magnitud de la señal generalmente inspecciona el bit de signo y utiliza una lógica diferente.


La ventaja de realizar la resta por el método del complemento es la reducción en el hardware
complejidad. No son necesarios los diferentes circuitos digitales para sumar y restar. Ambas sumas y restas se realizan solo por sumadores.


Leyendo las respuestas a esta pregunta, me encontré con este comentario [editado].

El complemento de 2 de 0100 (4) será 1100. Ahora 1100 es 12 si digo normalmente. Entonces, cuando digo normal 1100, entonces es 12, pero cuando digo 2 complementan 1100, entonces es -4? Además, en Java cuando se almacena 1100 (supongamos que 4 bits por ahora) se almacena, ¿cómo se determina si es +12 o -4? - Hagrawal 2 de julio a las 16:53

En mi opinión, la pregunta formulada en este comentario es bastante interesante, por eso me gustaría en primer lugar reformularla y luego dar una respuesta y un ejemplo.

PREGUNTA: ¿Cómo puede el sistema establecer cómo se deben interpretar uno o más bytes adyacentes? En particular, ¿cómo puede el sistema establecer si una secuencia de bytes dada es un número binario simple o un número de complemento de 2?

RESPUESTA - El sistema establece cómo interpretar una secuencia de bytes a través de tipos. Tipos definen

  • cuántos bytes deben considerarse
  • cómo esos bytes deben ser interpretados

EJEMPLO - A continuación, suponemos que

  • char son de 1 byte de largo
  • short tienen 2 bytes de largo
  • int y float tienen una longitud de 4 bytes

Tenga en cuenta que estos tamaños son específicos de mi sistema. Aunque son bastante comunes, pueden ser diferentes de un sistema a otro. Si tiene curiosidad de lo que son en su sistema, use el operador sizeof .

En primer lugar, definimos una matriz que contiene 4 bytes e inicializamos todas ellas en el número binario 10111101 , que corresponde al número hexadecimal BD .

// BD(hexadecimal) = 10111101 (binary) unsigned char l_Just4Bytes[ 4 ] = { 0xBD, 0xBD, 0xBD, 0xBD };

Luego leemos el contenido de la matriz usando diferentes tipos.

unsigned char y signed char

// 10111101 as a PLAIN BINARY number equals 189 printf( "l_Just4Bytes as unsigned char -> %hi/n", *( ( unsigned char* )l_Just4Bytes ) ); // 10111101 as a 2''S COMPLEMENT number equals -67 printf( "l_Just4Bytes as signed char -> %i/n", *( ( signed char* )l_Just4Bytes ) );

unsigned short y short

// 1011110110111101 as a PLAIN BINARY number equals 48573 printf( "l_Just4Bytes as unsigned short -> %hu/n", *( ( unsigned short* )l_Just4Bytes ) ); // 1011110110111101 as a 2''S COMPLEMENT number equals -16963 printf( "l_Just4Bytes as short -> %hi/n", *( ( short* )l_Just4Bytes ) );

unsigned int , int y float

// 10111101101111011011110110111101 as a PLAIN BINARY number equals 3183328701 printf( "l_Just4Bytes as unsigned int -> %u/n", *( ( unsigned int* )l_Just4Bytes ) ); // 10111101101111011011110110111101 as a 2''S COMPLEMENT number equals -1111638595 printf( "l_Just4Bytes as int -> %i/n", *( ( int* )l_Just4Bytes ) ); // 10111101101111011011110110111101 as a IEEE 754 SINGLE-PRECISION number equals -0.092647 printf( "l_Just4Bytes as float -> %f/n", *( ( float* )l_Just4Bytes ) );

Los 4 bytes en RAM ( l_Just4Bytes[ 0..3 ] ) permanecen siempre exactamente iguales. Lo único que cambia es cómo los interpretamos.

De nuevo, le decimos al sistema cómo interpretarlos a través de los tipos .

Por ejemplo, arriba hemos utilizado los siguientes tipos para interpretar los contenidos de la matriz l_Just4Bytes

  • unsigned char : 1 byte en binario simple
  • signed char : 1 byte en complemento a 2
  • unsigned short : 2 bytes en notación binaria simple
  • short : 2 bytes en complemento a 2
  • unsigned int : 4 bytes en notación binaria simple
  • int : 4 bytes en complemento a 2
  • float : 4 bytes en notación de precisión simple IEEE 754

[EDITAR] Esta publicación se ha editado después del comentario de user4581301. ¡Gracias por tomarse el tiempo para dejar caer esas pocas líneas útiles!


Para expandir las respuestas de los demás:

En complemento a dos

  • Agregar es el mismo mecanismo que la suma simple de enteros positivos.
  • Restar no cambia demasiado
  • ¡Multiplicación también!

La división requiere un mecanismo diferente.

Todo esto es cierto porque el complemento a dos es simplemente la aritmética modular normal, en la que optamos por ver algunos números como negativos restando el módulo.


Puedes ver al profesor Jerry Cain de Stanford explicando el complemento de los dos, en la segunda conferencia (la explicación sobre el complemento a 2 comienza alrededor de las 13:00) en la serie de conferencias llamada Paradigmas de programación disponible para ver desde el canal de YouTube de Standford. Aquí está el enlace a la serie de conferencias: http://www.youtube.com/view_play_list?p=9D558D49CA734A02 .


Se hace para que la adición no necesite tener ninguna lógica especial para tratar con números negativos. Mira el artículo en Wikipedia .

Supongamos que tiene dos números, 2 y -1. En su forma "intuitiva" de representar números, serían 0010 y 1001 , respectivamente (me estoy quedando con 4 bits para el tamaño). En la forma de complemento a dos, son 0010 y 1111 . Ahora, digamos que quiero agregarlos.

La adición del complemento a dos es muy simple. Agrega números normalmente y cualquier bit de acarreo al final se descarta. Entonces se agregan de la siguiente manera:

0010 + 1111 =10001 = 0001 (discard the carry)

0001 es 1, que es el resultado esperado de "2 + (- 1)".

Pero en su método "intuitivo", agregar es más complicado:

0010 + 1001 = 1011

¿Cuál es -3, verdad? La adición simple no funciona en este caso. Debe tener en cuenta que uno de los números es negativo y usa un algoritmo diferente si ese es el caso.

Para este método de almacenamiento "intuitivo", la resta es una operación diferente de la suma, lo que requiere comprobaciones adicionales de los números antes de que puedan agregarse. Como desea que las operaciones más básicas (sumas, restas, etc.) sean lo más rápidas posible, debe almacenar los números de una manera que le permita utilizar los algoritmos más simples posibles.

Además, en el método de almacenamiento "intuitivo", hay dos ceros:

0000 "zero" 1000 "negative zero"

Que son intuitivamente el mismo número pero tienen dos valores diferentes cuando se almacenan. Cada aplicación deberá realizar pasos adicionales para asegurarse de que los valores distintos de cero tampoco sean negativos cero.

Hay otra ventaja con el almacenamiento de entradas de esta manera, y es entonces cuando necesitas ampliar el ancho del registro en el que se almacena el valor. Con el complemento a dos, almacenar un número de 4 bits en un registro de 8 bits es una cuestión de repetir su parte más significante:

0001 (one, in four bits) 00000001 (one, in eight bits) 1110 (negative two, in four bits) 11111110 (negative two, in eight bits)

Solo se trata de mirar el signo de la palabra más pequeña y repetirla hasta que rellene el ancho de la palabra más grande.

Con su método, debería borrar el bit existente, que es una operación adicional además del relleno:

0001 (one, in four bits) 00000001 (one, in eight bits) 1010 (negative two, in four bits) 10000010 (negative two, in eight bits)

Aún necesita configurar esos 4 bits adicionales en ambos casos, pero en el caso "intuitivo" también debe borrar el 5to bit. Es un pequeño paso extra en una de las operaciones más fundamentales y comunes presentes en cada aplicación.


Se usa el complemento de dos porque es más simple de implementar en los circuitos y tampoco permite un cero negativo.

Si hay x bits, el complemento a dos oscilará entre + (2 ^ x / 2 + 1) y - (2 ^ x / 2). El complemento de uno se ejecutará de + (2 ^ x / 2) a - (2 ^ x / 2), pero permitirá un cero negativo (0000 es igual a 1000 en un sistema de complemento de 4 bits 1).


Solo realizamos operaciones de adición para suma y resta. Agregamos el segundo operando al primer operando para sumar. Para la resta, agregamos el complemento 2 del segundo operando al primer operando.

Con una representación de complemento de 2 no necesitamos componentes digitales separados para la resta, solo se usan sumadores y complementadores.


Una respuesta satisfactoria de por qué Two2''s Complement se usa para representar números negativos en lugar del complemento One es que el sistema Two''s Complement resuelve el problema de múltiples representaciones de 0 y la necesidad de end-around-carry que existe en el sistema complementario de One representando negativas números.

Para obtener más información, visite https://en.wikipedia.org/wiki/Signed_number_representations

Para visitar End-Around-carry https://en.wikipedia.org/wiki/End-around_carry


Una ventaja importante de la representación de complemento de dos que no se ha mencionado aún aquí es que los bits inferiores de una suma, diferencia o producto de complemento de dos dependen únicamente de los bits correspondientes de los operandos. La razón por la que el valor de 8 bit signed para -1 es 11111111 es que restando cualquier entero cuyos 8 bits más bajos son 00000001 de cualquier otro entero cuyos 8 bits más bajos son 0000000 dará un entero cuyos 8 bits más bajos son 11111111 . Matemáticamente, el valor -1 sería una cadena infinita de 1, pero todos los valores dentro del rango de un tipo entero particular serán todos 1 o todos pasarán a cierto punto, por lo que es conveniente que las computadoras "firmen-extiendan" el el bit más significativo de un número como si representara un número infinito de 1 o 0.

El complemento de dos es casi la única representación de número con signo que funciona bien cuando se trata de tipos más grandes que el tamaño de palabra natural de una máquina binaria, ya que al realizar sumas o restas, el código puede buscar el trozo más bajo de cada operando, calcular el menor el resultado, y almacene eso, luego cargue el siguiente fragmento de cada operando, calcule el siguiente fragmento del resultado y almacénelo, etc. Por lo tanto, incluso un procesador que requiera todas las adiciones y sustracciones para pasar por un solo registro de 8 bits puede manejar números con signo de 32 bits de manera razonablemente eficiente (más lento que con un registro de 32 bits, por supuesto, pero aún funciona).

Al usar cualquier otra representación firmada permitida por el Estándar C, cada bit del resultado podría verse afectado por cualquier bit de los operandos, por lo que es necesario mantener un valor completo en los registros a la vez o bien seguir los cálculos con un extra paso que, al menos en algunos casos, requeriría leer, modificar y volver a escribir cada parte del resultado.


Vale la pena observar que en algunas máquinas de adición temprana, antes de los días de las computadoras digitales, la resta se realizaba haciendo que el operador ingresara valores usando un conjunto de leyendas de diferente color en cada tecla (para que cada tecla ingresara nueve menos el número que se restado), y presionar un botón especial asumiría un acarreo en un cálculo. Por lo tanto, en una máquina de seis dígitos, para restar 1234 de un valor, el operador presionaría las teclas que normalmente indicaban "998,765" y presionar un botón para agregar ese valor más uno al cálculo en progreso. La aritmética de complemento a dos es simplemente el equivalente binario de la aritmética anterior de "complemento de diez".


esto es para simplificar sumas y diferencias de números. una suma de un número negativo y uno positivo codificado en complementos de 2 es lo mismo que sumarlos de la manera normal.


Wikipedia permite que la suma y la resta se realicen de la manera normal (como si estuvieras enrollado para números sin signo). También previene -0 (una forma separada de representar 0 que no sería igual a 0 con el método normal de bit a bit de comparación de números).


Wikipedia dice todo:

El sistema de dos complementos tiene la ventaja de no requerir que los circuitos de suma y resta examinen los signos de los operandos para determinar si sumar o restar. Esta propiedad hace que el sistema sea más simple de implementar y capaz de manejar fácilmente una aritmética de mayor precisión. Además, el cero tiene una sola representación, obviando las sutilezas asociadas con el cero negativo, que existe en los sistemas complementarios de uno.

En otras palabras, agregar es lo mismo, ya sea que el número sea negativo o no.