Electrónica Digital · Tema 04

Binario y hexadecimal

Ya sabés qué voltaje es un bit y cuándo cambia. Ahora hay que contar con ellos. El silicio cuenta en base 2 porque solo distingue dos niveles; vos vas a leerlo en base 16 porque es el binario con letra legible. Este tema es la gramática de todo lo que sigue.

≈ 40 minutos Sin materiales: solo el navegador Incluye simulador y Python

01 · Punto de partida

Diez dedos, dos niveles

Contamos de a diez porque tenemos diez dedos. Un cable digital tiene dos estados, así que su «aritmética natural» es de a dos: un cable, un bit; ocho cables, ocho bits, 256 combinaciones. Todo lo que un circuito digital sabe de números lo sabe en base 2.

Una escena típica. Un colega te pasa el color de un botón: #FF5733. Otro te dice que un permiso de archivo es chmod 755. Una placa te informa que la dirección de su pantalla OLED es 0x3C. Tres notaciones distintas y, debajo de todas, lo mismo: grupos de bits, escritos de la forma más cómoda para quien los lee.

Si ya programás, esas notaciones te cruzan el camino todos los días. Lo que cambia ahora es que aprendés qué hay debajo: cada dígito hexadecimal es cuatro cables, y cada cable vale una potencia de dos.

  • ¿Cómo se lee un número binario con los pesos de cada posición?
  • ¿Cómo se pasa de decimal a binario y de binario a hexadecimal sin calculadora?
  • ¿Cuánto entra en 4, 8, 12 o 16 bits?
  • ¿Qué son MSB y LSB, y por qué el orden importa?
  • ¿Qué hacen los desplazamientos y las máscaras?

02 · Sistema posicional

Contar con pesos, no con magia

El decimal ya es un sistema posicional: en 305 el «3» vale 300 porque está en la posición de las centenas. Cada posición vale 10 veces la anterior. El binario hace lo mismo con una sola diferencia: cada posición vale el doble.

Los mismos pesos en base 10 y en base 2 (de derecha a izquierda).
Posición01234567
Peso en base 10110100100010 000100 00010⁶10⁷
Peso en base 21248163264128

Un número binario se lee sumando el peso de cada posición donde hay un 1. Por ejemplo, 1101 tiene unos en los pesos 8, 4 y 1:

Contar en binario es contar igual que en decimal, pero «se acaban los dígitos» antes: al llegar a 1 hay que llevarse uno a la posición siguiente.

Contar de 0 a 15 con cuatro bits.
DecBinarioDecBinarioDecBinarioDecBinario
000004010081000121100
100015010191001131101
2001060110101010141110
3001170111111011151111

Fijate en cómo cambia cada bit al contar de 0 a 15 en orden: el de la derecha alterna 0, 1, 0, 1 en cada número; el siguiente alterna cada dos números; el siguiente cada cuatro. Cada bit cambia a la mitad de velocidad que el anterior. Esa observación es exactamente cómo funciona un contador digital (curso 6).

Bit
Un dígito binario: 0 o 1. Es la unidad mínima de información y, en hardware, un cable.
Nibble
Un grupo de 4 bits. Vale de 0 a 15 y corresponde a exactamente un dígito hexadecimal.
Byte
Un grupo de 8 bits (dos nibbles). Vale de 0 a 255.
Palabra (word)
El ancho natural de un procesador: 8, 16, 32 o 64 bits. Depende del chip.

03 · Conversión

Decimal ↔ binario

Hay dos métodos para pasar un decimal a binario. Los dos sirven; conviene dominar el primero para cuentas rápidas y el segundo para entender cómo lo haría un programa.

  1. 1
    Restar la potencia más grande.

    Para 165: la mayor potencia que entra es 128 (queda 37); luego 32 (queda 5); luego 4 (queda 1); luego 1. Los pesos usados son 128, 32, 4 y 1 → 10100101. Se marca 1 donde se restó y 0 donde se saltó.

  2. 2
    Dividir por 2 y anotar los restos.

    165 ÷ 2 = 82 resto 1; 82 ÷ 2 = 41 resto 0; 41 ÷ 2 = 20 resto 1; y así hasta llegar a 0. Los restos, leídos de abajo hacia arriba, son los bits: 10100101.

  3. 3
    Binario a decimal: sumar pesos.

    Para 1101: 8 + 4 + 0 + 1 = 13. En un programa se hace recorriendo los bits de izquierda a derecha con v = v * 2 + bit (lo vas a ver en la sección 08).

decimal→ restar potencias de 2 →unos y ceros→ agrupar de a 4 →hexadecimal

04 · Hexadecimal

Binario con buena letra

Un número binario largo es difícil de leer y de copiar sin errores: 1010010111000011 mareó a cualquiera. El hexadecimal (base 16) resuelve eso con un truco: cada dígito hexadecimal representa exactamente un nibble. No hay que calcular nada, solo agrupar de a cuatro.

Nibble a hexadecimal (0 a 15). Las letras A–F valen 10 a 15.
BinDecHexBinDecHex
000000100088
000111100199
001022101010A
001133101111B
010044110012C
010155110113D
011066111014E
011177111115F

Para pasar de binario a hexadecimal se parte el número en grupos de 4 bits, de derecha a izquierda, y se reemplaza cada grupo por su dígito:

Para pasar de hexadecimal a decimal: el primer dígito pesa 16 y el segundo pesa 1. En 0xA5: 10 × 16 + 5 = 165. Con más dígitos, cada posición pesa 16 veces la anterior (1, 16, 256, 4096…).

Hexadecimal en cosas que ya usás.
DóndeEjemploQué significa
Color web#FF5733Rojo 0xFF = 255, verde 0x57 = 87, azul 0x33 = 51: un byte por canal
Dirección I²C0x3CDirección típica de una pantalla OLED: 0011 1100 = 60
Dirección MACA4:CF:12:…Seis bytes, cada uno escrito con dos dígitos hexadecimales
Registro de un chip0xFFLos ocho bits en uno: «todo activado»
Permisos Unix755 (octal)111 101 101: tres grupos de tres bits (rwx r-x r-x)

05 · Rangos

Cuánto entra por ancho

Con N bits hay 2N combinaciones distintas, así que se pueden representar los números de 0 a 2N − 1 (sin signo). Cada bit extra duplica la capacidad.

Rango sin signo por ancho de bits.
BitsCombinacionesRangoDónde lo ves
120 – 1Un cable, un bit
4160 – 15Nibble, un dígito hexadecimal, display de 7 segmentos
82560 – 255Byte, canal de color, ADC simple, 0xFF
1010240 – 1023Entrada analógica de una placa Arduino
1240960 – 4095ADC de muchos microcontroladores
1665 5360 – 65 535uint16_t, números de puerto TCP
32≈ 4300 millones0 – 4 294 967 295uint32_t, direcciones IPv4

La pregunta inversa también aparece: ¿cuántos bits necesito para guardar hasta el valor M? Se busca la menor N tal que 2N − 1 ≥ M. Para 100 valores distintos hacen falta 7 bits (rango 0 a 127); para 1000, 10 bits (0 a 1023); para 5000, 13 bits.

06 · Orden y manipulación

MSB, LSB, desplazamientos y máscaras

Los bits de un número no valen todos lo mismo. El de más a la izquierda, con el peso mayor, es el MSB (most significant bit); el de la derecha, de peso 1, es el LSB (least significant bit). Tocar el MSB de 165 resta 128; tocar el LSB resta 1.

Orden en serie (endianness)
Cuando los bits viajan uno a uno por un cable, hay que acordar cuál sale primero: MSB primero o LSB primero. La UART del Tema 2 enviaba el LSB primero; SPI suele enviar el MSB primero. Si emisor y receptor no acuerdan, un 0x41 se lee como 0x82.
Desplazar a la izquierda (<<)
Mover todos los bits una posición a la izquierda y entrar un 0 por la derecha. Equivale a multiplicar por 2. 45 << 1 = 90. Si el MSB se pierde, el resultado deja de ser correcto.
Desplazar a la derecha (>>)
Mover los bits una posición a la derecha. Equivale a dividir por 2 (descartando el resto). 45 >> 1 = 22.
Máscara con AND (&)
Para leer ciertos bits: poner en 0 todo lo que no interesa. x & 0x0F deja solo el nibble bajo.
OR (|) y XOR (^)
OR con una máscara enciende bits; XOR los invierte. x | 0x80 pone el MSB en 1; x ^ 0xFF invierte los ocho bits.

Estas operaciones son lo que el hardware hace «gratis»: un desplazamiento no es un cálculo sino un recableado, y una máscara es una puerta AND por bit (Temas 8 y 9). Por eso los programadores de bajo nivel las usan tanto para configurar registros.

07 · Simulador

Laboratorio: ocho interruptores

El simulador muestra un byte como ocho interruptores. Prendé y apagá bits, movés el deslizador o aplicás operaciones, y mirá cómo cambian el decimal, el hexadecimal y la suma de pesos. También te dice qué voltaje representaría ese byte en un conversor de 8 bits con rango de 0 a 5 V (el puente con el Tema 1).

  • Cajas amarillas: los bits en 1. Debajo de cada una se ve el peso que aporta a la suma.
  • Corchetes bajo las cajas: los dos nibbles. Encima de cada uno, el dígito hexadecimal que le corresponde.
  • Botones de operación: desplazar, invertir, sumar y restar 1. El mensaje inferior te avisa cuando un desplazamiento pierde un bit.
SIMULADOR 04

Un byte, ocho interruptores

165 = 0xA5

Un byte como ocho bits Ocho cajas con los bits del byte, el peso de cada posición, la suma de pesos y los dos dígitos hexadecimales de los nibbles. BYTE · 8 BITS · 2 NIBBLES
Binario1010 0101
Hexadecimal0xA5
Suma de pesos128+32+4+1
Como ADC de 8 bits (5 V)3,24 V

Recorrido guiado (5 minutos)

  1. 1
    Mirá el byte inicial (165).

    Los unos están en los pesos 128, 32, 4 y 1. Los nibbles son 1010 (A) y 0101 (5): el hexadecimal sale de leerlos sin calcular.

  2. 2
    Apagá el bit de 128 y después el de 1.

    El primero resta 128 (165 → 37) y el segundo resta 1 (165 → 164). Mismo gesto, impacto distinto: el peso manda.

  3. 3
    Armá 255 con los ocho interruptores.

    Todo en 1 = 0xFF, el máximo de un byte. Ahora apretá «+ 1»: el resultado es 0. Es el desborde del apartado 05: no da error, da la vuelta.

  4. 4
    Con 45 (00101101) apretá «<< 1» varias veces.

    45 → 90 → 180: se duplica en cada paso. Al siguiente (360) no cabe en 8 bits: el MSB se pierde y queda 104. El mensaje avisa del desborde.

  5. 5
    Con 165 apretá «>> 1».

    165 → 82 → 41: se divide por 2 y el bit que sale por la derecha se descarta. Dividir y luego multiplicar no devuelve el original.

  6. 6
    Apretá «Invertir (NOT)» sobre 165.

    Los 1 pasan a 0 y viceversa: 165 (10100101) se vuelve 90 (01011010). Siempre se cumple que x + NOT(x) = 255 en 8 bits.

Preguntas para pensar

  1. Armá 0x3C con los interruptores. ¿Cuál es su decimal y qué interruptores están encendidos?
  2. ¿Qué diferencia hay, en valor decimal, entre apagar el MSB de 165 y apagar su LSB?
  3. Partiendo de 1, ¿cuántas veces podés aplicar «<< 1» antes de perder el único bit en 1?
Ver respuestas sugeridas
  1. 0x3C = 0011 1100 = 60 = 32 + 16 + 8 + 4. Están encendidos los interruptores 32, 16, 8 y 4 (las posiciones 3, 4, 5 y 6 contando desde el MSB).
  2. Apagar el MSB resta 128 (de 165 a 37); apagar el LSB resta solo 1 (a 164). El peso de cada posición decide cuánto cambia el valor.
  3. Siete veces: 1 → 2 → 4 → 8 → 16 → 32 → 64 → 128. A la octava vez el bit sale por la izquierda y el resultado es 0.

08 · Bases en código

Convertir sin calculadora (y verificar)

Python ya sabe de bases, pero escribir las conversiones a mano fija la idea. Primero mostrá un número en las tres notaciones, después reproducí los algoritmos del apartado 03.

Python en tu navegador. Los bloques son editables: cambiá los valores y presioná «Ejecutar Python». La primera vez tarda unos segundos en cargar.

Paso 1: un número, tres notaciones

def mostrar(n, bits=8):
    b = format(n, f"0{bits}b")
    h = format(n, f"0{bits // 4}X")
    suma = " + ".join(str(2 ** (bits - 1 - i)) for i, c in enumerate(b) if c == "1") or "0"
    print(f"{n:>3} = {b[:bits // 2]}_{b[bits // 2:]} = 0x{h}  ({suma})")
    return b


for n in (165, 13, 255, 60, 0):
    mostrar(n)

165 = 1010_0101 = 0xA5. 13 = 0000_1101 = 0x0D. ¿Qué número es 0x3C? ¿Y con bits=16?

Paso 2: de binario a decimal (sumar pesos)

def a_decimal(txt):
    v = 0
    for ch in txt.replace("_", "").strip():
        v = v * 2 + (ch == "1")
    print(f"{txt} = {v} = 0x{v:X}")
    return v


a_decimal("1101")
a_decimal("10100101")
a_decimal("00111100")

Cada vuelta duplica lo acumulado y suma el bit nuevo. Probá "11111111" y "1000_0000".

Paso 3: de decimal a binario (dividir por 2)

def divisiones(n):
    pasos, x = [], n
    while x:
        pasos.append(f"{x}/2 = {x // 2} resto {x % 2}")
        x //= 2
    print(f"{n}:", " | ".join(pasos))
    print("  restos leídos al revés:", format(n, "b"))


divisiones(13)
divisiones(165)

13 da 6, 3, 1, 0 con restos 1, 0, 1, 1: leídos al revés, 1101. ¿Cuántas divisiones necesita un número de 8 bits?

Paso 4: ¿cuántos bits necesito?

def bits_necesarios(maximo):
    n = 1
    while 2 ** n - 1 < maximo:
        n += 1
    print(f"para llegar a {maximo} hacen falta {n} bits (rango 0..{2 ** n - 1})")
    return n


for m in (1, 9, 100, 255, 256, 1000, 4095, 5000):
    bits_necesarios(m)

255 cabe en 8 bits y 256 ya necesita 9: un solo valor de más cuesta un bit entero. ¿Cuántos bits para guardar los minutos de un día (1440)?

Paso 5: desplazamientos, máscaras y un color

x = 0b00101101
print(f"x = {x:08b} ({x})")
print(f"x << 1 = {(x << 1) & 0xFF:08b} ({(x << 1) & 0xFF})   "
      f"x << 2 = {(x << 2) & 0xFF:08b} ({(x << 2) & 0xFF})")
print(f"x >> 1 = {x >> 1:08b} ({x >> 1})")

y = 0b11001101
print(f"y << 1 en 8 bits = {(y << 1) & 0xFF:08b}: se pierde el bit {(y >> 7) & 1}")

print(f"x & 0x0F = {x & 0x0F:08b}   x & 0xF0 = {x & 0xF0:08b}")
print(f"x | 0x80 = {x | 0x80:08b}   x ^ 0xFF = {x ^ 0xFF:08b}")


def color(hexa):
    h = hexa.lstrip("#")
    r, g, b = (int(h[i:i + 2], 16) for i in (0, 2, 4))
    print(f"#{h.upper()} -> R={r} G={g} B={b}  ({r:08b} {g:08b} {b:08b})")


color("#FF5733")
color("#00FF7F")
color("#808080")

45 << 1 = 90 y 45 >> 1 = 22 (se pierde el resto). #FF5733 es R=255, G=87, B=51. ¿Qué color es #808080? ¿Y #000000?

09 · Analogía de programador

Flags, volcados y máscaras

Casi todo lo de este tema ya lo usaste sin llamarlo así. Poné nombre a esas herramientas y la electrónica pasa a ser conocida.

El mismo concepto, en dos mundos.
En softwareEn electrónica digital
Un campo de flags (O_RDWR | O_CREAT)Un registro donde cada bit enciende una función del chip
Un volcado de memoria en hexBinario compacto: cada dígito es un nibble exacto
uint8_t, uint16_t, uint32_tBuses de 8, 16 y 32 cables
x << 1 en lugar de x * 2Un recableado: sin hardware aritmético
x & 0xFF para quedarse con un byteUna puerta AND por bit con una máscara fija
Un overflow de enteroEl acarreo que no tiene dónde ir (Tema 23)
Un color #RRGGBBTres bytes pegados: 24 bits en un bus
  1. 1
    Bits = flags.

    Los permisos Unix 755 son tres grupos de tres bits: el binario ya gobierna tus archivos.

  2. 2
    Hex = volcado legible.

    Ver memoria en hexadecimal es ver binario con buena letra. Cada dígito, un nibble exacto.

  3. 3
    Pesos = potencias de 2.

    128, 64, 32… están por todas partes: 1 KiB son 1024 bytes, los puertos TCP llegan a 65 535, los colores tienen 256 niveles.

La diferencia con un lenguaje de programación es que ahí el ancho lo declarás con un tipo y el compilador te cuida las espaldas. En el hardware, el ancho es la cantidad de cables que tendiste: si el número no cabe, no hay error ni excepción, simplemente se pierde el bit que no tiene dónde ir.

10 · Comprensión

Confusiones frecuentes

«El hexadecimal es otro sistema que hay que calcular»

Es binario agrupado de a cuatro. 0xA5 no se calcula: se lee (1010 y 0101). Solo cuando querés el decimal hay que multiplicar. Para la electrónica el hexadecimal casi nunca se pasa a decimal.

«0b10 vale diez»

0b10 vale 2. El prefijo cambia la base. Leer «10» sin saber la base es como leer «5» sin unidad: ¿cinco metros o cinco kilos? Siempre explicitá la base (0b, 0x o un subíndice).

«Con 8 bits alcanza para todo»

255 se queda corto para 1000, no tiene signo y es poco para el ADC de 10 o 12 bits. El ancho se elige por el rango que necesitás (apartado 05), no por costumbre.

«El orden de los bits da igual»

Si el emisor manda primero el MSB y el receptor espera el LSB, cada byte llega espejado: 0x41 se lee como 0x82. Hay que acordar el orden antes de cablear o programar.

«Un número más grande solo ocupa más lugar»

En hardware el lugar es fijo. Un valor que no cabe en su ancho no genera un error: se trunca o da la vuelta (255 + 1 = 0 en 8 bits). Los desbordes se evitan con un ancho suficiente o con una comprobación explícita.

«Dividir por 2 con >> es siempre exacto»

Con números enteros descarta el resto: 45 >> 1 = 22, no 22,5. Para un número impar, multiplicar de nuevo no devuelve el original. En hardware no hay «mitad de un bit».

11 · Práctica guiada

Ejercicios de bases

Ejercicio 1: contar hasta 15

Escribí a mano los números de 0 a 15 en binario de 4 bits. Después verificá el 13 y el 10 con a_decimal().

Ver solución razonada

La lista es 0000, 0001, 0010, … 1111. El 13 es 1101 (8 + 4 + 1) y el 10 es 1010 (8 + 2), que en hexadecimal es A. Contar en binario es sumar 1 con acarreo: cada vez que un bit pasa de 1 a 0, el siguiente a la izquierda sube.

Ejercicio 2: de hexadecimal a decimal

Convertí 0x1F, 0x80 y 0xC3 a decimal a mano. Verificá con int("C3", 16).

Ver solución razonada

31, 128 y 195. 0x1F = 1 × 16 + 15; 0x80 = 8 × 16 y es el MSB de un byte; 0xC3 = 12 × 16 + 3 = 192 + 3. En binario: 0001 1111, 1000 0000 y 1100 0011.

Ejercicio 3: DIP switch

Un DIP switch de 8 posiciones (numeradas 1 a 8 con el MSB primero) debe quedar en 0x3C, la dirección de una pantalla OLED. ¿Qué posiciones van en ON?

Ver solución razonada

0x3C = 0011 1100. Van en ON las posiciones 3, 4, 5 y 6; las demás en OFF. Leer un DIP switch es leer binario con los dedos. (Atención: algunos DIP numeran desde el LSB; siempre mirá la serigrafía.)

Ejercicio 4: elegir el ancho

Un sensor de posición entrega 600 posiciones distintas. Otro cuenta hasta 1440 minutos de un día. ¿Cuántos bits necesita cada uno? Verificá con bits_necesarios().

Ver solución razonada

Para 600 valores (0 a 599) alcanzan 10 bits (hasta 1023); 9 bits llegan solo a 511. Para llegar a 1439 hacen falta 11 bits (hasta 2047); 10 bits llegan a 1023. En ambos casos, sobra algo: es el costo de trabajar con potencias de dos.

Ejercicio 5: descomponer un color

El color #FF5733 tiene tres bytes. Pasalos a decimal y a binario. ¿Qué color da cada canal por sí solo y cuánto aporta el verde en porcentaje?

Ver solución razonada

R = 0xFF = 255 = 11111111 (rojo al máximo); G = 0x57 = 87 = 01010111; B = 0x33 = 51 = 00110011. El verde aporta 87 / 255 ≈ 34 % y el azul 20 %. El resultado es un naranja rojizo: mucho rojo, algo de verde y poco azul. Con tres bytes se codifican 224 ≈ 16,7 millones de colores.

12 · Síntesis

Ideas para recordar

  • Un número binario es la suma de los pesos de sus unos: 128, 64, 32, 16, 8, 4, 2, 1.
  • Decimal a binario: restar la potencia más grande o dividir por 2 y leer los restos al revés.
  • Un dígito hexadecimal es un nibble exacto: 0xA5 = 1010 0101 = 165. Se lee agrupando, sin calcular.
  • N bits dan 2N valores, de 0 a 2N − 1. Cada bit extra duplica la capacidad.
  • Un número que no cabe no da error: da la vuelta (255 + 1 = 0 en 8 bits).
  • El MSB pesa mucho y el LSB ajusta; en serie hay que acordar cuál sale primero.
  • Desplazar es multiplicar o dividir por 2; una máscara AND lee bits; OR enciende; XOR invierte.
  • Poné siempre la base: 0b para binario, 0x para hexadecimal.

¿Listo para el Tema 5?

Podés avanzar si sos capaz de responder esto sin mirar:

  • Convertir 100 a binario y a hexadecimal sin calculadora.
  • Leer 0xC3 como bits y como decimal.
  • Decir cuántos valores distintos hay en 10 bits y cuál es el máximo.
  • Calcular cuántos bits hacen falta para contar hasta 300.
  • Explicar qué le pasa a 255 al sumarle 1 en un byte.
  • Describir qué hacen << 1, & 0x0F, | 0x80 y ^ 0xFF.

Ya sabés contar en la base del silicio. Ahora, ¿cómo se escribe un número negativo, un carácter o una fecha con bits? En el próximo tema, representación de información digital.