Saltar al contenido principal
LibreTexts Español

7.4: Binario (base 2)

  • Page ID
    117551
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    La otra base que comúnmente usamos en informática es la base 2, o binaria. Esto se debe a que la unidad básica de información en una computadora se llama bit, que tiene sólo dos valores, convencionalmente llamados “true” y “false” o “1" y “0". Los números (así como todo lo demás) se representan en última instancia como secuencias colosales de 1's y 0's, que son, por supuesto, números binarios.

    Las reglas para interpretar el valor posicional son las mismas:\[\begin{aligned} \text{110101}_{2} &= 1 \times 2^5 + 1 \times 2^4 + 0 \times 2^3 + 1 \times 2^2 + 0 \times 2^1 + 1 \times 2^0 \\ &= 1 \times 32 + 1 \times 16 + 0 \times 8 + 1 \times 4 + 0 \times 2 + 1 \times 1 \\ &= \text{53}_{10}.\end{aligned}\] Así que en binario tenemos un lugar de uno, un lugar de dos, un lugar de cuatro, un lugar de ocho, y así sucesivamente. Llamamos al lugar más a la derecha el bit menos significativo (LSB) y el más a la izquierda el bit más significativo (MSB).

    Contar desde cero es realmente lo mismo que cualquier otra base, aunque se siente un poco extraño en binario porque “vuelves” tan a menudo:

    \(\texttt{0}_2\) cero
    \(\texttt{1}_2\) uno
    \(\texttt{10}_2\) dos
    \(\texttt{11}_2\) tres
    \(\texttt{100}_2\) cuatro
    \(\texttt{101}_2\) cinco
    \(\texttt{110}_2\) seis
    \(\texttt{111}_2\) siete
    \(\texttt{1000}_2\) ocho
    \(\texttt{1001}_2\) nueve

    Convertir a y desde decimal

    La conversión de binario a decimal se demostró arriba (con\(110101_2=53_{10}\).) Para ir por el otro lado, seguimos el algoritmo de la página. Vamos a probarlo para el número decimal 49:

    1. (Paso 1) Primero computamos 49 mod 2. Hacer “mod 2" es fácil: solo ves si el número es par o impar. En este caso, es extraño, por lo que el resto es un 1:

      1

    2. (Paso 2) Ahora divide 49 por 2 y toma la palabra, lo que da\(\lfloor \text{49} \div 2 \rfloor = 24\). No es cero, así que realizamos el paso 2.2: hacer 24 nuestro nuevo valor, mover nuestro lápiz a la izquierda del 1, y volver al paso 1.

    3. (Paso 1) Calcula 24 mod 2. Ya que 24 es par, esto es cero, que escribimos a la izquierda del 1:

      01

    4. (Paso 2) Divide 24 por 2 y toma la palabra, lo que da\(\lfloor \text{24} \div 2 \rfloor = 12\). Haz 12 nuestro nuevo valor, mueve nuestro lápiz a la izquierda del 0, y vuelve al paso 1.

    5. (Paso 1) Calcula 12 mod 2. Ya que 12 es par, esto es cero, que escribimos:

      001

    6. (Paso 2) Divide 12 por 2 y toma la palabra, lo que da\(\lfloor \text{12} \div 2 \rfloor = 6\). Haz 6 nuestro nuevo valor, mueve nuestro lápiz a la izquierda del 0, y vuelve al paso 1.

    7. (Paso 1) Calcula 6 mod 2. Ya que 6 es par, esto es cero, que escribimos:

      0001

    8. (Paso 2) Divide 6 por 2 y toma la palabra, lo que da\(\lfloor \text{6} \div 2 \rfloor = 3\). Haz 3 nuestro nuevo valor, mueve nuestro lápiz a la izquierda del 0, y vuelve al paso 1.

    9. (Paso 1) Calcula 3 mod 2. Ya que 3 es impar, este es uno, que escribimos:

      10001

    10. (Paso 2) Divide 3 por 2 y toma la palabra, lo que da\(\lfloor \text{3} \div 2 \rfloor = 1\). Esto todavía no es cero, así que haz de 1 nuestro nuevo valor, mueve nuestro lápiz a la izquierda del 0, y vuelve al paso 1.

    11. (Paso 1) Calcula 1 mod 2. Ya que 1 es impar, este es uno, que escribimos:

      110001

    12. (Paso 2) Divide 1 por 2 y toma la palabra, lo que da\(\lfloor \text{1} \div 2 \rfloor = 0\). Ya terminamos. La respuesta final es\(110001_2\). Comprobando dos veces nuestro trabajo, verificamos que efectivamente uno 32 más uno 16 más uno 1 da 49, que es con lo que empezamos.

    Conversión a y desde hex

    Eso fue bastante tedioso. Pero la conversión de un lado a otro de binario a hexadecimal es un broche de presión. Eso es porque 16 es exactamente\(2^4\), y así un dígito hexadecimal es exactamente igual a cuatro dígitos binarios. Este no es el caso con base 10, donde un dígito decimal es igual a tres dígitos binarios... más un poco más. Esta cosa de “no un número entero de dígitos” es lo que hace que convertir de decimal a binario (o decimal a hexadecimal, para el caso) sea tan incómodo.

    Lo más común es tratar con conjuntos de ocho bits a la vez, que se llama byte. (Esta es la unidad fundamental de almacenamiento en casi todas las computadoras de la tierra). Supongamos que tenía el siguiente byte:

    \(\texttt{10000110}_2\)

    Debido a que un dígito hexadecimal es exactamente igual a cuatro bits, este byte es exactamente igual a:

    \(\texttt{86}_{16}\)

    Esto se debe a que el byte se puede dividir ordenadamente en dos partes: 1000, que corresponde al dígito hexadecimal 8, y 0110, que corresponde al dígito hexadecimal 6. Estas dos mitades se llaman mordisqueos: un byte tiene dos mordisqueos, y cada mordisco es un dígito hexadecimal. De un vistazo, por lo tanto, sin multiplicar ni sumar, podemos convertir de binario a hexadecimal.

    Ir en otra dirección es igual de fácil. Si tenemos:

    \(\texttt{3E}_{16}\)

    simplemente convertimos cada dígito hexadecimal en el mordisqueado correspondiente:

    \(\texttt{00111110}_2\)

    Después de hacer esto un rato, llegas al punto en el que puedes reconocer instantáneamente qué dígito hexadecimal va con qué valor de mordisco. Hasta entonces, sin embargo, aquí hay una mesa práctica:

    mordisquear dígito hexadecimal
    0000 0
    0001 1
    0010 2
    0011 3
    0100 4
    0101 5
    0110 6
    0111 7
    1000 8
    1001 9
    1010 A
    1011 B
    1100 C
    1101 D
    1110 E
    1111 F

    Por si te lo estás preguntando, sí vale la pena memorizar esto.

    Sumando números binarios

    Agregar dos números binarios es lo mismo que sumar en decimal, hexadecimal, o cualquier otra base: solo hay que saber cuándo “rodar sobre el odómetro”, que en este caso es casi instantáneamente, ya que el valor más alto que un bit puede contener es ¡1! Vamos a darle una oportunidad:\[\begin{array}{*{7}{c@{\hspace{0pt}}}} & 1 & 1& 1&0 &0&1_2\\ +& 0 & 1 & 1 & 0 & 1 & 0_2 \\  \hline &  & & &  &  & ?_2 \\ \end{array}\] Un niño podría seguir las reglas: cuando agregamos dos ceros, obtenemos cero. Agregar un uno a un cero da uno. Al sumar dos unos se obtiene cero, y un acarreo al siguiente dígito significativo. Y agregar dos más un acarreo da uno y un acarreo. Vea si puede seguir el flujo:\[\begin{array}{*{7}{c@{\hspace{0pt}}}} & 1&1 & & &&\\ & 1 & 1 & 1 & 0 & 0 & 1_2 \\ + & 0 & 1 & 1 & 0 & 1 & 0_2 \\ \hline 1 & 0 & 1 & 0 & 0 & 1 & 1_2 \\ \end{array}\]

    Capacidad

    ¿Qué tan grande puede almacenar un valor un byte? Hay 8 bits, y cada uno puede tener independientemente cualquiera de dos valores (0 o 1), así que por el Teorema Fundamental del Conteo, existen\(2^8\) diferentes combinaciones. Esto funciona a 256, pero en realidad no podemos almacenar el número 256 en un byte si estamos usando el patrón de bits\(\texttt{00000000}_2\) (o\(\texttt{00}_{16}\)) para representar cero. El valor más alto sería\(\texttt{11111111}_2\) (o\(\texttt{FF}_{16}\)), que es\(256_{10}\).

    ¿Cómo almacenamos un número mayor que ese? Simplemente use más de un byte, por supuesto. Si usáramos dos bytes de memoria, y los tratáramos como concatenados uno tras otro, eso nos daría 16 bits, permitiéndonos almacenar hasta el número\(\texttt{0000000000000000}_2\) =\(\texttt{FFFF}_{16}\) =\(\text{65,535}_{10}\). Llamaríamos a uno de estos bytes —el que representa el lugar\(2^0\)'s hasta el lugar\(2^7\) del 's— el byte menos significativo, y al otro —que contiene los lugares\(2^8\) a través\(2^{15}\) — el byte más significativo. Extender a más de dos bytes para acomodar números aún mayores se hace de la manera obvia.

    Esquemas de representación binaria

    Eso es sobre todo todo lo que hay para ello. Pero hay una cosa que aún no hemos discutido, y eso son los números negativos. Sabemos representar cualquier número positivo (o cero) con un esquema de valor posicional ordinario. Pero, ¿cómo almacenamos un número como\(-5\)?

    Existen tres esquemas diferentes para tratar números negativos, cada uno con sus fortalezas y debilidades.

    Sin firmar

    El esquema más simple se llama sin signo, y simplemente significa que no permitimos números negativos. Para un byte, tenemos 256 patrones de bits diferentes a nuestra disposición, y podríamos elegir asignarlos todos para representar números positivos, a fin de obtener el rango más amplio. Esto tiene sentido para, digamos, una variable de programa C++ llamada heightIninches que sabemos que nunca puede ser significativamente negativa (nadie tiene una altura negativa).

    La ventaja de este esquema es simplemente que podemos representar el mayor rango posible de números positivos, que a veces es el objetivo. Cada uno de los esquemas alternativos talla una parte de estos patrones de bits disponibles y los dedica a representar números negativos, dejando menos sobra para los números positivos. No hay almuerzo gratis: tienes que decidir cómo quieres “gastar” tus patrones de bits disponibles dependiendo de qué valores necesites representar.

    Signo-Magnitud

    El esquema de signo-magnitud es probablemente lo primero que pensaría para resolver el problema de representación numérica negativa. Necesitamos almacenar el signo del número de alguna manera, y un signo es inherentemente una cosa de dos valores (ya sea positivo o negativo), entonces ¿por qué no despegar uno de los bits y usarlo para representar el signo? Los bits restantes se pueden usar entonces de la manera ordinaria para representar la magnitud del número.

    La forma en que esto se hace más a menudo es tomar el bit más a la izquierda y usarlo como bit de signo. Este bit ahora no tiene otro significado. No puede “doblarse” como el lugar de los 128, porque entonces no habría manera de distinguir entre, digamos, 129 y\(-129\) (cada uno estaría representado con 10000001.) No, el bit de signo debe considerarse “dinero gastado”, y su poder expresivo no puede ser reclamado para representar también parte de la magnitud. Por convención, si el bit de signo es 0 esto representa un número positivo, y un bit de signo de 1 representa un número negativo. (Eso puede parecer contrario a la intuición, pero bueno, así es como es).

    Entonces este número en signo-magnitud:

    0 0100110

    representa el número decimal 38. Eso es porque el bit de signo (en negrilla, en el extremo izquierdo) es 0, lo que significa que el número es positivo. La magnitud del número está contenida en los otros 7 bits, lo que da 32 + 4 + 2 = 38. Este número, por otro lado:

    1 0100110

    representa\(-38\). La magnitud es la misma, pero el bit de signo es 1 por lo que este patrón ahora “significa” un número negativo.

    Claramente hemos reducido nuestro rango de números positivos a cambio de la capacidad de almacenar también negativos. Tenemos 7 bits de rango en lugar de 8, así que en lugar de 255, nuestro valor más alto posible es simplemente 127. En el otro extremo, el valor más bajo posible es\(-127\).

    Si tienes los ojos agudos, es posible que hayas notado una discrepancia en el conteo. Con el enfoque de signo-magnitud, podemos mantener números en el rango\(-127\) de 127. Pero espera: ¡eso solo son 255 valores diferentes, no 256! ¿Por qué perdimos un valor de poder expresivo? La respuesta es que el esquema signo-magnitud tiene dos formas de representar cero. El patrón de bits 00000000 es obviamente cero, pero también lo es 10000000 (que podrías llamar “cero negativo”). Usar dos patrones diferentes para representar el mismo valor es un poco derrochador, pero la situación en realidad es peor que eso. Tener que dar cuenta de ambos patrones significa que el hardware de la computadora que utiliza el esquema de signo-magnitud es inevitablemente más complicado. Para comparar dos bytes para ver si son iguales, pensarías que solo compararíamos cada posición de bit, y si todos fueran iguales, los bytes serían declarados iguales, de lo contrario no. Por desgracia, esto ya no es tan sencillo. Los dos patrones cero deben considerarse numéricamente iguales, por lo que nuestra lógica digital ahora tiene que contener un caso especial. “Para ser iguales, todos los bits tienen que ser iguales... oh, pero en realidad no si los siete más a la derecha son todos ceros en ambos bytes. En ese caso, no importa lo que contenga el bit más a la izquierda”. Enloquecedora.

    Complemento de dos

    Esta deficiencia en el esquema de signo-magnitud se remedia con el esquema de dos complementos, que es el que realmente se usa con más frecuencia en la práctica. Parecerá extraño al principio —ciertamente no tan intuitivo como los dos primeros— pero lleva a una característica críticamente importante que veremos en breve.

    Primero, las reglas. Para interpretar un número de complemento de dos, usted:

    1. Mira el bit más a la izquierda (al igual que en signo-magnitud). Si es un 0, tienes un número positivo. Si es un 1, tienes un número negativo.

    2. Si es un número positivo, los otros 7 bits te dan la magnitud (igual que en signo-magnitud).

    3. Si, sin embargo, es un número negativo, entonces para descubrir la magnitud de ese número negativo debes voltear todos los bits y sumar uno. Esto le dará un número positivo que es el valor absoluto de su número negativo.

    Ejemplo fácil: tomar el byte 00100110. El bit más a la izquierda es un 0, lo que significa que es un número positivo, y como descubrimos anteriormente, los 7 bits restantes dan una magnitud de 38. Entonces este es el número 38.

    Ejemplo más duro: tomar el byte 10100110. El bit más a la izquierda es un 1, lo que significa que es negativo. Bien: ¿negativo qué? ¿Cómo encontramos la magnitud? Bueno, “volteamos” todos los bits (es decir, invertimos cada uno de 0 a 1 o viceversa) para obtener:

    01011001

    y luego agregar uno al resultado:\[\begin{array}{*{9}{c@{\hspace{0pt}}}} & & & & & & & 1 & \\ & 0 & 1& 0 & 1 & 1 & 0 & 0 & 1 \\ + & &  & &  & & && 1\\ \hline & 0 & 1 & 0& 1 &1 &0 &1 & 0\\ \end{array}\] Esta magia negra produce el valor\(\texttt{01011010}_2\), que se convierte en\(90_{10}\). Esto significa que el número original, 10100110, corresponde al valor —90.

    “Voltear todos los bits y agregar uno” es el procedimiento del libro de cocina para tomar el complemento (negativo) de un número en el esquema del complemento de dos. También funciona a la inversa. Empecemos con 90 esta vez y volvamos a pasar por el proceso, asegurándonos de que obtengamos —90.

    Comienza con la representación binaria de\(90_{10}\):\[\begin{array}{*{8}{c@{\hspace{0pt}}}} \texttt{0} & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{0} \\ \end{array}\] Voltear todos los bits para obtener:\[\begin{array}{*{8}{c@{\hspace{0pt}}}} \texttt{1} & \texttt{0} & \texttt{1} & \texttt{0} & \texttt{0} & \texttt{1} & \texttt{0} & \texttt{1} \\ \end{array}\] y finalmente sumar uno al resultado:\[\begin{array}{*{9}{c@{\hspace{0pt}}}} & & & & & & & \texttt{1} & \\ & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{0} & \texttt{0} & \texttt{1} & \texttt{0} & \texttt{1} \\ + & & \texttt{ } & \texttt{ } & \texttt{ } & \texttt{ } & \texttt{ } & \texttt{ } & \texttt{1} \\ \hline & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{0} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} \\ \end{array}\] Obtenemos 10100110, que era precisamente el número con el que comenzamos originalmente, y que ya tenemos determinado representa —90.

    Ahora puede preguntarse qué ganamos con todo esto. Seguramente este esquema es considerablemente más complicado que la simple idea de reservar un poco como bit de signo, y tratar el resto como una magnitud. Pero resulta que efectivamente hay un método para la locura. Por extraño que parezca, un esquema de representación de dos complementos nos permite realizar sumas y restas con una sola operación.

    En primer grado (más o menos), aprendiste el procedimiento para sumar números de varios dígitos, que hemos seguido varias veces en este capítulo. Implica agregar los dígitos de derecha a izquierda y posiblemente “llevar”. Después en segundo grado (más o menos), aprendiste el procedimiento para restar números de varios dígitos. Implica restar los dígitos de derecha a izquierda y posiblemente “pedir prestado”. Si eres como yo, te pareció más fácil sumar que restar. Es fácil simplemente llevar el uno, pero pedir prestado requiere mirar el dígito a la izquierda, asegurándose de que pueda pedir prestado de él (es decir, que no es ya 0), pedir prestado desde más a la izquierda hasta que realmente encuentre un valor disponible distinto de cero, esperando que el número en la parte inferior sea en realidad menos que el de arriba (porque de lo contrario tienes que cambiar el orden y luego agregar un signo negativo al resultado), y manteniendo todo eso recto mientras marchas por la línea.

    Aunque no encontraras restar más difícil que sumar, sin embargo, no puedes argumentar que sigue siendo un algoritmo completamente diferente, con reglas diferentes a seguir. En el hardware de la computadora, tenemos que implementar diferentes circuitos para realizar cada operación, lo cual es más difícil, costoso, propenso a errores y drenaje de energía.

    Lo maravilloso del complemento de dos, sin embargo, es que con este esquema en realidad nunca necesitamos usar el algoritmo de resta. Si queremos restar dos números —digamos,\(24 - 37\) — podemos en cambio tomar el complemento del segundo número y luego sumarlos. En lugar de\(24-37\) computar\(24 + (-37)\).

    Vamos a verlo en acción. Usando procedimientos de conversión, podemos averiguar que\(24_{10}\) es:\[\begin{array}{*{8}{c@{\hspace{0pt}}}} \texttt{0} & \texttt{0} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{0} & \texttt{0} \\ \end{array}\] y eso positivo\(37_{10}\) es:\[\begin{array}{*{8}{c@{\hspace{0pt}}}} \texttt{0} & \texttt{0} & \texttt{1} & \texttt{0} & \texttt{0} & \texttt{1} & \texttt{0} & \texttt{1} \\ \end{array}\] Si quisiéramos calcular\(24+37\), solo agregaríamos estos. Pero en cambio estamos buscando\(24-37\), así que tomaremos el complemento de 37 para encontrar\(-37\). Voltear todos los bits de 37:\[\begin{array}{*{8}{c@{\hspace{0pt}}}} \texttt{1} & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{0} \\ \end{array}\] y sumar uno:\[\begin{array}{*{9}{c@{\hspace{0pt}}}} \texttt{1} & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{0} \\ + & \texttt{ } & \texttt{ } & \texttt{ } & \texttt{ } & \texttt{ } & \texttt{ } & \texttt{1} \\ \hline \texttt{1} & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{1} \\ \end{array}\] y así ahora hemos determinado que en el esquema de dos complementos,\(-37\) está representado por\(\texttt{11011011}_2\).

    Ahora estamos listos para calcular\(24 + (-37)\):\[\begin{array}{*{9}{c@{\hspace{0pt}}}{l}} & & & \texttt{1} & \texttt{1} & & & & \\ & \texttt{0} & \texttt{0} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{0} & \texttt{0} & \quad {\leftarrow this\space is\space 24_{10}}\\ + & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{1} & \quad {\leftarrow this\space is\space -37_{10}}\\ \hline & \texttt{1} & \texttt{1} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{0} & \texttt{1} & \texttt{1} & \\ \end{array}\]

    Entonces tenemos nuestra respuesta de complemento de dos, 11110011. ¿A qué valor corresponde eso? Bueno, el bit más a la izquierda es un 1, entonces es un número negativo. Para saber de qué es lo negativo, voltea todos los bits y agrega uno:\[\begin{array}{*{8}{c@{\hspace{0pt}}}{l}} \texttt{0} & \texttt{0} & \texttt{0} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{0} & \quad {\leftarrow flip\space the\space bits\space to\space get}\\ + & \texttt{ } & \texttt{ } & \texttt{ } & \texttt{ } & \texttt{ } & \texttt{ } & \texttt{1} & \quad {\leftarrow add\space one}\\ \hline \texttt{0} & \texttt{0} & \texttt{0} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{1} \\ \end{array}\] Esto es positivo 13, lo que significa que el número que invertimos para obtenerlo —11110011 — debe representar\(-13\). Y esa es efectivamente la respuesta correcta, para\(24-37=-13\).

    Una última palabra sobre el complemento de dos: ¿cuál es el rango de números que podemos representar? Resulta ser -128 a 127. El valor más alto es 01111111, que es 127. Podrías pensar que el valor más bajo se representaría como 11111111, pero si lo calculas, encontrarás que este es en realidad el número\(-1\). El número más bajo es en realidad el patrón de bits 10000000, que es\(-128\).

    Desbordamiento

    Un último detalle pegajoso que necesitamos cubrir tiene que ver con desbordamiento. Cuando sumamos dos números, existe la posibilidad de que el resultado contenga un dígito más que los números originales. Probablemente hayas visto esto en una calculadora de mano cuando presionas “=” y obtienes una “E" (para “error”) en la pantalla. Si solo hay diez dígitos en tu pantalla, agregar dos números de diez dígitos (a veces) resultará en un número de once dígitos que tu calculadora no puede mostrar, y te está alertando de ese hecho para que no malinterpretes el resultado. Aquí, podríamos agregar dos cantidades de 8 bits y terminar con una cantidad de 9 bits que no puede caber en un byte. Esta situación se llama desbordamiento, y necesitamos detectar cuándo ocurre.

    Las reglas para detectar desbordamiento son diferentes dependiendo del esquema. Para números sin signo, la regla es simple: si se realiza un 1 desde el MSB (extremo izquierdo), entonces tenemos desbordamiento. Entonces, si tuviera que intentar sumar\(155_{10}\) y\(108_{10}\):\[\begin{array}{*{9}{c@{\hspace{0pt}}}{l}} & \texttt{1} & \texttt{1} & \texttt{1} & \texttt{1} & & & & \\ & \texttt{1} & \texttt{0} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{1} & \quad {\leftarrow 155_{10}}\\ + & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{0} & \quad {\leftarrow 108_{10}}\\ \hline \texttt{1} & \texttt{0} & \texttt{0} & \texttt{0} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{1} & \texttt{1} \\ \end{array}\] entonces me queda un carry out en el dígito 9. Ya que solo podemos contener ocho dígitos en nuestro resultado, obtendríamos una respuesta sin sentido (\(15_{10}\)), la cual podemos detectar como falsa porque la realización indicaba desbordamiento.

    Signo-magnitud funciona de la misma manera, excepto que tengo un bit menos cuando estoy agregando y almacenando resultados. (En lugar de un byte de bits que representan la magnitud, el bit del extremo izquierdo se ha reservado para un propósito especial: indicar el signo del número. Por lo tanto, si agrego las cantidades restantes de 7 bits y obtengo un carry out dejado en el octavo dígito, eso indicaría desbordamiento.)

    Ahora con el complemento de dos, las cosas (predeciblemente) no son tan fáciles. Pero resulta que son casi igual de fáciles. Todavía hay una regla simple para detectar desbordamiento, es solo una regla diferente. La regla es: si el carry in al último bit (más a la izquierda) es diferente al carry out del último bit, entonces tenemos desbordamiento.

    Intentemos sumar\(103_{10}\) y\(95_{10}\) en dos-complemento, dos números que caben en nuestro rango -128 a 127, pero cuya suma no:\[\begin{array}{*{9}{c@{\hspace{0pt}}}{l}} {\text{carry-in}} \rightarrow & \texttt{1} & \texttt{1} & \texttt{1} & \texttt{1} & \texttt{1} & \texttt{1} & \texttt{1} & \\ & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{1} & \quad {\leftarrow 103_{10}}\\ \quad + & \texttt{0} & \texttt{1} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{1} & \texttt{1} & \texttt{1} & \quad {\leftarrow 95_{10}}\\ \hline {\text{carry-out}} \rightarrow \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} & \texttt{0} & \texttt{0} & \texttt{1} & \texttt{1} & \texttt{0} \\ \end{array}\] El carry-in al último bit fue 1, pero el carry-out fue 0, así que para el complemento de dos esto significa que detectamos desbordamiento. También es algo bueno, ya que 11000110 en dos-complemento representa\(-57_{10}\), que ciertamente no es 103 + 95.

    Esencialmente, si el carry-in no es igual al carry-out, eso significa que agregamos dos números positivos y se nos ocurrió un número negativo, o que agregamos dos negativos y obtuvimos un positivo. Claramente este es un resultado erróneo, y la simple comparación nos dice eso. Solo tenga cuidado de darse cuenta de que la regla para detectar desbordamiento depende totalmente del esquema de representación particular que estemos usando. Una realización de 1 siempre significa desbordamiento... en el esquema sin firmar. Para el complemento de dos, podemos obtener fácilmente una carga de 1 sin ningún error, siempre que el equipaje de mano también sea 1.

    “Todo es relativo”

    Por último, si salimos al aire de toda esta masa de detalles, vale la pena enfatizar que no existe una manera intrínsecamente “correcta” de interpretar un número binario. Si te muestro un patrón de bits —digamos, 11000100 — y te pregunto qué valor representa, no puedes decirme sin saber interpretarlo.

    Si digo, “oh, ese es un número sin signo”, entonces tratarías cada bit como un dígito en un simple esquema de numeración base 2. Se agregaría\(2^7 + 2^6 + 2^2\) para obtener 196, luego respondería, “ah, entonces ese es el número\(196_{10}\). Y tendrías razón.

    Pero si digo, “oh, ese es un número de signo-magnitud”, primero mirarías el bit más a la izquierda, verías que es un 1, y te darías cuenta de que tienes un número negativo. Entonces tomarías los siete bits restantes y los tratarías como dígitos en un simple esquema de numeración base 2. Se agregaría\(2^6 + 2^2\) para obtener 68, y luego responder, “ah, entonces ese es el número\(-68_{10}\). Y tendrías razón.

    Pero, de nuevo, si digo, “oh, ese es un número de complemento de dos”, primero mirarías el bit más a la izquierda, verías que es un 1 y te darías cuenta de que estás tratando con un número negativo. ¿De qué es lo negativo? Voltearías todos los bits y agregarías uno para averiguarlo. Esto te daría\(\texttt{00111100}\), que interpretarías como un número base 2 y obtendrías\(60_{10}\). Entonces responderías, “ah, entonces ese es el número\(-60_{10}\). Y tendrías razón.

    Entonces, ¿qué representa 11000100?? ¿Es 196,\(-68\), o\(-60\)? La respuesta es cualquiera de las tres, dependiendo del esquema de representación que estés usando. Ninguno de los datos en computadoras o sistemas de información tiene un significado intrínseco: todo tiene que ser interpretado de acuerdo con las reglas sintácticas y semánticas que inventamos. En matemáticas e informática, cualquier cosa se puede hacer que signifique cualquier cosa: después de todo, inventamos las reglas.


    This page titled 7.4: Binario (base 2) is shared under a not declared license and was authored, remixed, and/or curated by Stephen Davies (allthemath.org) via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.