¿Por qué la computadora usa el complemento de 2 para almacenar el número negativo en lugar del complemento de 1?

Para revisar : el formato de complemento a dos dice que para obtener el negativo de un entero, invierta cada bit y agregue 1 . Entonces, el valor negativo de 0000 0001 no es 1111 1110 sino 1111 1111. (Por cierto, debería ver de inmediato la superioridad de este sistema, porque un número impar como 1 o -1 debería terminar con un 1, no un 0.) ¿Por qué es esto mejor?

De acuerdo, supongamos que es un diseñador de chips de CPU y necesita diseñar un chip que admita operaciones “firmadas” y “no firmadas” de la manera más eficiente posible. Comienza por admitir las instrucciones ADD, SUB y MULT “sin signo”, en las que las operaciones “sin signo” suponen que cada cantidad es 0 o positiva. Pero ahora desea admitir ADD, SUB y MULT “firmados” haciendo el menor trabajo adicional posible.

Además, y esto es importante, ha diseñado su chip para que sumar 1 al valor de todos los 1s (1111 1111 1111 1111) “se voltea” para producir todos los 0, como un odómetro. No arroja una ejecución ni causa un error.

Resulta que el sistema de complemento de dos satisface estas necesidades maravillosamente mientras que el sistema de complemento de uno no. La forma más simple de ver esto es que cualquier X agregada a -X debería producir cero, pero puede ver fácilmente que produce todos los 1:

0000 0001 + 1111 1110 = 1111 1111 (1 + -1 en el complemento)

Esencialmente, lo que sucede en el complemento de 1 (solo invierte cada bit para obtener el negativo de un número) es que cero obtiene dos representaciones diferentes: 00000000 y 111111111.

Y eso ya es un gran problema. ¿Por qué? Porque usted, el diseñador de chips, ha escrito instrucciones eficientes que prueban la igualdad de dos números. Tener dos representaciones diferentes para cero ya ha dificultado las cosas al obligarlo a hacer un trabajo adicional para ver si dos números, cada uno igual a cero, son iguales entre sí. Lo que debemos hacer en esta situación es forzar el resultado a “voltear” a 0000 0000. Que es lo que el complemento de dos hace implícitamente.

0000 0001 + 1111 1111 = 0000 0000 (1 + -1 en complemento de dos)

Y el problema es aún mayor de lo que estoy implicando. Debido a que el complemento de uno representa cero de dos maneras diferentes (0000 0000 y 1111 1111), arroja todas las matemáticas cuando estás contando de negativo a positivo. Imagine contar hacia arriba desde -2:

Complemento de uno: -2, -1, 0, 0, 1, 2 …

Complemento de dos: -2, -1, 0, 1, 2 …

Ahora debería poder ver que con el sistema de complemento de uno, todas las matemáticas saldrán mal cuando agregue números positivos y negativos. ¡En particular, no quiero agregar 1 a cero y obtener cero nuevamente! ¡Y no quiero agregar 3 a -1 y obtener 1!

O más bien, necesitaría un conjunto adicional de instrucciones al agregar números positivos y negativos, y (debido a lo que dije antes), no quiere eso. Esa es una gran cantidad de trabajo extra, y complejidad adicional para poner en su chip.

Pero con el complemento de dos, algunos experimentos demostrarán que las mismas instrucciones que suman dos números sin signo (digamos 255 + 2 para producir 257, que se voltea para producir 1) también admitirán la operación con signo equivalente (en este caso, -1 + 2 = 1).

Mi punto es, y esto es crítico, puede ver la misma operación que “255 + 2 = 1” o puede verla como “-1 + 2 = 1” sin ningún cambio en el cableado del chip. Ambos son igualmente “correctos” … el primero es “correcto” porque hemos estipulado que es el comportamiento correcto para que las cantidades excesivamente grandes “se vuelquen” como un odómetro.

De una manera pequeña, casi trivial, el complemento a dos complica nuestro diseño de chip. Ahora debemos admitir la negación lógica bit a bit y la negación aritmética como dos instrucciones distintas. Pero este es un pequeño precio a pagar por las ventajas que he mostrado para el complemento de dos.

Negación lógica bit a bit: invierte cada bit individual

Negación aritmética (tome el negativo de un número) : invierta cada bit individual y luego agregue 1.

Cuando agrega un complemento de dos a un número, es equivalente a la resta, mientras que el complemento de uno no resulta en una resta. Esto significa que solo necesita un sumador en la CPU y puede realizar la operación en un solo paso, en lugar de varios pasos.