TEMA 10 - Representación
interna de los datos.
INDICE
1. Introducción
1.1 Concepto de representación interna de los datos
1.2 Importancia en sistemas informáticos y comunicación digital
2. Sistemas de numeración
2.1 Sistema binario: base 2, dígitos y peso de las posiciones
2.2 Sistema octal (base 8) y sistema hexadecimal (base 16): agrupación de
bits
2.3 Conversión entre sistemas (decimal ↔ binario/octal/hexadecimal)
2.4 Aritmética básica en binario: suma, resta, multiplicación y división
3. Representación de datos enteros y con signo
3.1 Enteros sin signo: rango y almacenamiento en un byte, palabra, etc.
3.2 Enteros con signo: complemento a 1 y complemento a 2
3.3 Desbordamiento (overflow) y underflow en operaciones binarias
4. Representación de datos en punto flotante (reales)
4.1 Formato IEEE 754 de simple precisión (32 bits): signos, exponente y
mantisa
4.2 Formato IEEE 754 de doble precisión (64 bits)
4.3 Rango, precisión y errores de redondeo
4.4 Conversión entre decimal y punto flotante IEEE 754
5. Representación de datos alfanuméricos
5.1 Código ASCII: estándar de 7/8 bits, mayúsculas, minúsculas, símbolos
5.2 Código Unicode: principio, planes y puntos de código
5.3 Formatos de codificación Unicode: UTF-8, UTF-16, UTF-32
5.4 Ventajas y usos de cada codificación en entornos multilingües
6. Representación de datos gráficos y multimedia
6.1 Imágenes estáticas
6.1.1 Mapas de bits (BMP, RAW): resolución, profundidad de color (1, 8, 24
bits)
6.1.2 Paletas y compresión sin pérdida (PNG, GIF)
6.1.3 Compresión con pérdida (JPEG): muestreo cromático, DCT
6.2 Audio digital
6.2.1 Muestreo y cuantificación (frecuencia, bits de muestreo)
6.2.2 PCM (Pulse Code Modulation)
6.2.3 Compresión con pérdida (MP3, AAC) y sin pérdida (FLAC)
6.3 Vídeo digital
6.3.1 Secuencia de imágenes (frames) y frecuencia de muestreo (fps)
6.3.2 Códecs y estándares (MPEG-2, H.264, H.265): GOP, I-P-B frames
7. Agrupación y estructuras básicas en memoria
7.1 Byte, palabra, doble palabra: alineación y direccionamiento
7.2 Endianess: Big Endian vs Little Endian y su repercusión en intercambio
de datos
7.3 Estructuras de datos elementales: arrays, registros y cómo se
almacenan en memoria
8. Codificación de canal y corrección de errores
8.1 Bits de paridad (par/impar) para detección simple de errores
8.2 Códigos de Hamming para detección y corrección de errores simples
8.3 Códigos CRC (Cyclic Redundancy Check) para detección de errores en
redes
9. Representación y compresión
9.1 Principios de compresión sin pérdida (Run-Length, LZW)
9.2 Principios de compresión con pérdida aplicada a imágenes (JPEG) y
audio (MP3)
9.3 Ventajas e inconvenientes de cada método en almacenamiento y
transmisión
10. Relación con otros módulos del ciclo formativo
10.1 Sistemas informáticos:
- Arquitectura interna y jerarquía de memoria: importancia de la
representación de datos en RAM y caché
- Buses de datos y control: ancho de bus y formatos binarios de
transferencia
10.2 Bases de datos:
- Tipos de datos lógicos y numéricos: precisión de enteros y reales
- Operadores booleanos en consultas (WHERE A AND B, etc.)
10.3 Lenguajes de programación y entornos de desarrollo:
- Tipos de datos primitivos y estructuras internas en memoria
- Gestión de cadenas: ASCII vs Unicode en aplicaciones
10.4 Multimedia (Lenguajes de marcas y gestión de información):
- Tratamiento de imágenes y audio en entornos web (HTML5, CSS)
- Formatos y códecs compatibles con navegadores y reproductores
10.5 Redes e Internet:
- Representación de direcciones IP (IPv4 binario/decimal, IPv6
hexadecimal)
- Encapsulado de datos, comprobación de errores (CRC, checksum)
10.6 Seguridad informática:
- Fundamentos de cifrado simétrico y asimétrico: bit a bit, bloques de
datos
- Hashing: operación binaria sobre datos de longitud variable
10.7 Implantación de sistemas operativos:
- Formateo de discos y sistemas de archivos binarios (FAT32, NTFS, EXT4)
- Gestión de formatos de partición y direccionamiento lógico de bloques
11. Actividades prácticas para el alumnado
11.1 Conversión manual y programada entre sistemas de numeración
11.2 Diseño y simplificación de expresiones booleanas con mapas de
Karnaugh
11.3 Implementación de operaciones binarias (suma/resta en complemento
a 2) en pseudocódigo o Python
11.4 Codificación de cadenas en ASCII y UTF-8: representación y
almacenamiento en archivos
11.5 Construcción de un pequeño “visualizador” de imágenes BMP/PNG para
ver el almacenamiento de píxeles
11.6 Grabación de audio PCM y análisis de muestra y frecuencia usando
Audacity o similar
11.7 Simulación de detección de errores con bits de paridad y códigos de
Hamming en Logisim
11.8 Análisis comparativo de compresión JPEG vs PNG para una misma
imagen (calidad vs tamaño)
12. Conclusión
12.1 Importancia de la representación interna en todas las capas del
sistema informático
12.2 Necesidad de dominar estos conceptos para optimizar rendimiento,
compatibilidad y seguridad
12.3 Tendencias futuras: compresión avanzada, representaciones en
sistemas cuánticos, tecnologías emergentes
1. Introducción
1.1 Concepto de representación interna de los datos
La representación interna de los datos hace referencia a la forma en
que un sistema informático codifica, almacena y procesa la información en
su nivel más bajo (nivel de hardware). Todo dato—números, caracteres,
imágenes, audio—debe convertirse a estructuras de bits (ceros y unos) para
que la CPU, la memoria y los periféricos digitales puedan manipularlo.
Dato: unidad mínima de información con significado (por ejemplo, el
número 42, la letra 'A', un píxel de color).
Representación interna: secuencia de ceros y unos (bits) que el
hardware interpreta como ese dato.
Objetivo: permitir operaciones aritméticas, lógicas y de
almacenamiento mediante circuitos digitales.
En esencia, cada dato en el nivel de aplicación (por ejemplo, “temperatura
= 23,5 °C”) se traduce en un patrón de bits que, interpretado por la CPU,
corresponde a un código binario, entero o de punto flotante, etc.
1.2 Importancia en sistemas informáticos y comunicación digital
Compatibilidad y estandarización: Sin una representación interna
unificada (por ejemplo, el estándar IEEE 754 para números en punto
flotante, o ASCII/Unicode para texto), los distintos componentes y
software no podrían intercambiar datos de forma coherente.
Eficiencia de almacenamiento y procesamiento: Saber cómo se
codifican los valores en bits permite optimizar la cantidad de
memoria o disco utilizado y anticipar el comportamiento de
operaciones aritméticas (ej. desbordamientos).
Comunicación digital: En redes y protocolos de comunicación, los
datos viajan como secuencias de bits. Conocer su representación
interna es esencial para detectar errores (CRC, checksums), cifrar/de-
cifrar flujos de información y garantizar interoperabilidad.
Depuración y resolución de errores: Cuando una aplicación
muestra un valor incorrecto, a veces es necesario examinar su
representación en memoria (por ejemplo, interpretar un “corrupto” en
hex).
Seguridad: Muchos algoritmos criptográficos operan a nivel bit, así
como técnicas de ocultación y firma digital.
En resumen, la representación interna de los datos es la base que sustenta
toda la informática: sin ella no es posible que un programa almacene un
número, reconozca un carácter o intercambie información con otro equipo.
2. Sistemas de numeración
2.1 Sistema binario: base 2, dígitos y peso de las posiciones
En sistemas digitales, el sistema binario es el método fundamental para
codificar información porque solo utiliza dos dígitos (0 y 1), que
corresponden a los dos estados posibles de un circuito electrónico
(apagado/encendido).
Definición: Sistema de numeración en base 2.
Dígitos (bits): 0 y 1.
Peso de las posiciones: En un número binario N = bₙ₋₁ bₙ₋₂ … b₁ b₀,
cada bit bᵢ (0 o 1) multiplica 2ⁱ.
o Por ejemplo, el número binario 10110₂ se interpreta como
csharp
1·2⁴ + 0·2³ + 1·2² + 1·2¹ + 0·2⁰
= 16 + 0 + 4 + 2 + 0
= 22 (decimal)
Ventajas:
Mapeo directo a estado físico de puertas lógicas (0 = nivel bajo; 1 =
nivel alto).
Simplifica el diseño de circuitos digitales (AND, OR, XOR, etc.).
2.2 Sistema octal (base 8) y sistema hexadecimal (base 16):
agrupación de bits
Para facilitar la lectura y escritura de largas cadenas binarias, se emplean
sistemas de mayor base que agrupan bits:
Octal (base 8): Cada dígito octal equivale a 3 bits.
o Pesos de posición: 8⁰, 8¹, 8², …
o Rango de cada dígito: 0–7.
o Ejemplo: 101 110₂ → se agrupa de derecha a izquierda en
bloques de 3 bits: (10)(111)(0) → (010)(111)(0) para completar
tres bits en el primer bloque → 010₂ = 2₈; 111₂ = 7₈; 000₂ = 0₈.
Resultado: 270₈.
Hexadecimal (base 16): Cada dígito hex equivale a 4 bits.
o Pesos de posición: 16⁰, 16¹, 16², …
o Rango de cada dígito: 0–9 y A–F (10–15).
o Ejemplo: 1011 1110₂ → agrupar en bloques de 4: 1011₂ = B₁₆;
1110₂ = E₁₆ → BE₁₆.
Ventajas de octal/hexadecimal:
Reducción del número de dígitos al representar grandes cadenas
binarias.
Facilita la depuración y lectura de direcciones, valores de registro,
máscaras de bits.
Muy usado en manuales técnicos, dumps de memoria, direcciones
IPv6 (hexadecimal).
2.3 Conversión entre sistemas (decimal ↔
binario/octal/hexadecimal)
1. Decimal a binario (método de divisiones sucesivas):
o Dividir el número decimal entre 2.
o Registrar el residuo (0 o 1).
o Repetir con el cociente hasta que sea 0.
o El número binario se lee de abajo hacia arriba (último residuo →
primer bit).
o Ejemplo: 45₁₀:
45 ÷ 2 = 22, residuo 1 → b₀ = 1
22 ÷ 2 = 11, residuo 0 → b₁ = 0
11 ÷ 2 = 5, residuo 1 → b₂ = 1
5 ÷ 2 = 2, residuo 1 → b₃ = 1
2 ÷ 2 = 1, residuo 0 → b₄ = 0
1 ÷ 2 = 0, residuo 1 → b₅ = 1
→ 45₁₀ = 101101₂
2. Binario a decimal:
o Multiplicar cada bit por 2ᶦ y sumar.
o Ejemplo: 11011₂ = 1·2⁴ + 1·2³ + 0·2² + 1·2¹ + 1·2⁰ = 16 + 8 +
0 + 2 + 1 = 27₁₀.
3. Binario a octal/hexadecimal (agrupación):
o Agrupar bits de derecha a izquierda en grupos de 3 (octal) o 4
(hex).
o Convertir cada grupo al dígito correspondiente.
o Ejemplo: 11010110₂ a hex: (1101)(0110)₂ = D₁₆ 6₁₆ = D6₁₆.
4. Octal/hexadecimal a binario (tabla de equivalencias):
o Cada dígito octal → 3 bits; cada dígito hex → 4 bits.
o Ejemplo: 3A₁₆ → 3 = 0011₂, A = 1010₂ → 0011 1010₂.
5. Decimal a octal/hexadecimal:
o Primero convertir a binario y luego a la base deseada, o usar
divisiones sucesivas de 8 o 16.
o Ejemplo (decimal a hex usando divisiones): 254₁₀ ÷ 16 = 15,
residuo 14 → dígito E; 15 ÷ 16 = 0, residuo 15 → dígito F →
FE₁₆.
2.4 Aritmética básica en binario: suma, resta, multiplicación y
división
Suma en binario
Mismas reglas que decimal, pero base 2 y con acarreo cuando la
suma excede 1.
Tabla de verdad para suma de 1 bit (sumador completo):
Ci S Cout
AB
n (Suma) (acarreo)
000 0 0
001 1 0
010 1 0
011 0 1
100 1 0
101 0 1
110 0 1
111 1 1
Ejemplo: 1011₂ + 0110₂
1011
0110
[1]0 0 0 1 (explicación abajo)
paso a paso:
LSb: 1+0=1, carry=0
siguiente: 1+1+0(carried)=0, carry=1
siguiente: 0+1+1=0, carry=1
siguiente: 1+0+1=0, carry=1
acarreo final → se escribe como MSb adicional → 10001₂
Resta en binario
Se puede implementar restando con complemento a 2:
o Representar el sustraendo en complemento a 2.
o Sumar al minuendo.
o Si hay acarreo final, descartar; en caso de resultado negativo,
se expresa en complemento a 2.
Ejemplo: 7₁₀ (0111₂) − 3₁₀ (0011₂)
yaml
3 en complemento a 2: invertir bits de 0011 → 1100, sumar 1 → 1101₂.
Sumar 0111 + 1101:
0111
+ 1101
------------
1 0 1 0 0 (descartar el bit de acarreo → 0100₂ = 4₁₀)
Multiplicación en binario
Método similar al “producto parcial” en decimal pero con reglas base
2.
Cada dígito del multiplicador (0 o 1) multiplica la fila del multiplicando
(copia o cero), desplazada según posición.
Ejemplo: 101₂ × 11₂
scss
1 0 1 (multiplicando)
× 1 1 (multiplicador)
arduino
1 0 1 (101₂ × 1, sin desplazamiento)
1 0 1 (101₂ × 1, desplazado una posición)
1 1 1 1 = 15₁₀
markdown
#### **División en binario**
- Similar a división larga en decimal: se resta repetidamente múltiplos del
divisor del dividendo, desplazando bits.
- **Ejemplo**: 1101₂ (13₁₀) ÷ 10₂ (2₁₀)
Dividendo: 1 1 0 1
Divisor: 1 0 (2 bits)
13 ÷ 2 =
1. Tomar primer dígito 1 (<2) → llevar al siguiente: 11₂ (3₁₀), cabe 1 vez:
11₂ - 10₂ = 01₂ (1).
2. Bajar siguiente bit (0) → 010₂ (2₁₀): cabe 1 vez: 10₂ - 10₂ = 00₂.
3. Bajar siguiente bit (1) → 001₂ (1₁₀): cabe 0 veces → resta 000₂: resto
= 001₂.
Cociente: 110₂ (6₁₀), Resto: 1₂ (1₁₀), porque 13 = 6·2 + 1.
3. Representación de datos enteros y con signo
3.1 Enteros sin signo: rango y almacenamiento en un byte, palabra,
etc.
Definición: Un entero sin signo almacena únicamente valores no
negativos, utilizando todos sus bits para magnitud.
N bits permiten representar valores del 0 a 2ⁿ − 1.
o 1 byte (8 bits) → rango 0 … 255 (2⁸ − 1).
o 1 palabra suele referirse a 2 bytes (16 bits) → rango 0 … 65
535 (2¹⁶ − 1).
o 3 bytes (24 bits) → rango 0 … 16 777 215 (2²⁴ − 1).
o 4 bytes (32 bits) → rango 0 … 4 294 967 295 (2³² − 1).
Almacenamiento:
En memoria, un entero sin signo de N bits se guarda en forma binaria
pura, de mayor a menor peso de bit.
La arquitectura puede exigir alineación a direcciones múltiples de N/8
bytes.
Ejemplo (1 byte):
csharp
Valor decimal 13₁₀ → binario 00001101₂ → almacenado en 8 bits.
3.2 Enteros con signo: complemento a 1 y complemento a 2
Para representar valores negativos, se reserva un bit de signo. Existen
varios métodos; los más usados son complemento a 1 y complemento a
2.
3.2.1 Complemento a 1 (One’s Complement)
Convención: El bit más significativo (MSB) es bit de signo (0 =
positivo, 1 = negativo).
Para obtener la representación de un número negativo, se invierten
todos los bits de la representación sin signo del valor absoluto.
Rango para N bits:
o Valores representables: −(2ⁿ⁻¹ − 1) … + (2ⁿ⁻¹ − 1).
o P. ej., 8 bits → rango −127 … +127 (y existen dos ceros: +0 =
00000000₂, −0 = 11111111₂).
Ejemplo 8 bits (complemento a 1):
+5 → 00000101₂
−5 → invertir bits → 11111010₂
+0 → 00000000₂; −0 → 11111111₂ (equivalente, problema
conceptual).
3.2.2 Complemento a 2 (Two’s Complement)
Convención: MSB = bit de signo (0 = positivo, 1 = negativo); para
negativos se genera el complemento a 1 y se suma 1.
Rango para N bits:
o Valores representables: −2ⁿ⁻¹ … + (2ⁿ⁻¹ − 1).
o P. ej., 8 bits → −128 … +127.
Útil porque existe un único cero y las operaciones aritméticas
(suma/resta) funcionan igual que en enteros sin signo, ignorando el
acarreo final.
Cómo obtener complemento a 2:
1. Escribir valor absoluto en binario de N bits.
2. Invertir todos los bits (complemento a 1).
3. Sumar 1 al resultado.
Ejemplo 8 bits (complemento a 2):
+5 → 00000101₂
Invertir → 11111010₂
Sumar 1 → 11111011₂ (−5)
Rango: +127 = 01111111₂; −128 = 10000000₂.
3.3 Desbordamiento (overflow) y underflow en operaciones binarias
Overflow (desbordamiento) se produce cuando el resultado de una
operación aritmética excede el rango representable.
o En complemento a 2 de N bits, si la suma de dos números
con el mismo signo produce un resultado con signo opuesto,
hay overflow.
o P. ej., N = 8 bits: 01000000₂ (+64) + 01000000₂ (+64) =
10000000₂ (−128): overflow.
Underflow se usa más en punto flotante; para enteros se considera
también overflow si se resta un valor negativo demasiado grande.
o P. ej., en 8 bits complemento a 2: −100 + (−50) = resultado
menor que −128 → overflow.
Detección práctica:
Suma de signo igual, resultado con signo distinto → overflow.
En hardware, el flag de overflow (V) se activa para señales de
advertencia.
4. Representación de datos en punto flotante (reales)
Para representar números no enteros o con rango muy amplio, el estándar
IEEE 754 define formatos de punto flotante.
4.1 Formato IEEE 754 de simple precisión (32 bits): signo,
exponente y mantisa
Total: 32 bits divididos en 3 campos:
1. Signo (S): 1 bit (0 = positivo; 1 = negativo).
2. Exponente (E): 8 bits, con sesgo (bias) = 127.
3. Mantisa (M) o fracción: 23 bits, con “1” implícito en números
normalizados.
Valor representado:
scss
(−1)^S × (1.M)₂ × 2^(E − Bias)
Donde “1.M” significa que se antepone un “1” seguido de la fracción
M.
Exponentes especiales:
o E = 255 (todas 1s) → NaN (si M ≠ 0) o ±∞ (si M = 0).
o E = 0 (todas 0s) → números subnormales: (−1)^S × (0.M)₂ ×
2^(1 − Bias).
Ejemplo: Representar +5,75₁₀ en IEEE 754 32 bits:
1. Binario de 5,75 = 101,11₂ = 1,0111₂ × 2²
2. Signo S = 0 (positivo)
3. Exponente = 2 + 127 = 129 → 10000001₂
4. Mantisa M = 01110000000000000000000₂ (23 bits, se rellena con
ceros)
→ 0 10000001 01110000000000000000000₂
4.2 Formato IEEE 754 de doble precisión (64 bits)
Total: 64 bits divididos en:
1. Signo (S): 1 bit.
2. Exponente (E): 11 bits, sesgo = 1023.
3. Mantisa (M): 52 bits, con bit 1 implícito en normalizados.
Valor:
scss
(−1)^S × (1.M)₂ × 2^(E − 1023)
Exponentes especiales:
o E = 2047 → NaN o ±∞.
o E = 0 → subnormales: (−1)^S × (0.M)₂ × 2^(1 − Bias).
Proporciona mayor rango y precisión que simple precisión.
4.3 Rango, precisión y errores de redondeo
Rango dinámico (simple):
o Valor máximo ≈ ± (2 − 2⁻²³) × 2^(127).
o Valor mínimo normalizado ≈ ±1.0 × 2⁻¹²⁶; subnormales ≈ ±1.0
× 2⁻¹²³.
Precisión:
o Simple: ~7 dígitos decimales significativos.
o Doble: ~16 dígitos decimales.
Errores de redondeo:
o Al convertir fracciones decimales a binario (p. ej., 0,1₁₀ no tiene
representación finita en binario), se produce error de
cuantización.
o Operaciones aritméticas llevan pequeñas inexactitudes.
o Excepciones: NaN, infinito, subnormales y ceros con signo.
4.4 Conversión entre decimal y punto flotante IEEE 754
Pasos para simple precisión:
1. Determinar signo (S): 0 si número ≥ 0; 1 si < 0.
2. Obtener valor absoluto y escribir en binario (parte entera y
fraccionaria).
3. Normalizar en forma [Link]₂ × 2^k → determinar exponente k.
4. Calcular Exponente E = k + Bias (127), convertir a 8 bits.
5. Mantisa M: tomar bits después del punto decimal en la
representación normalizada (descartar el “1” implícito),
rellenar/cortar a 23 bits.
6. Formar 32 bits: S | E(8 bits) | M(23 bits).
Ejemplo: Representar −6,5₁₀ en simple precisión:
1. Signo S = 1.
2. 6,5₁₀ = 110,1₂ → normalizar: 1,101₂ × 2².
3. Exponente k = 2 → E = 2 + 127 = 129 → 10000001₂.
4. Mantisa: bits tras el punto de 1,101 → “101000…0” (relleno a 23 bits).
5. Resultado:
scss
S E(8) M(23)
1 10000001 10100000000000000000000₂
5. Representación de datos alfanuméricos
En informática, además de números, es esencial representar texto y
caracteres especiales. Existen distintos estándares que asignan a cada
caracter un código binario. A lo largo del tiempo se han estandarizado
principalmente ASCII y Unicode, con sus variantes de codificación.
5.1 Código ASCII: estándar de 7/8 bits, mayúsculas, minúsculas,
símbolos
Definición y contexto
ASCII (American Standard Code for Information Interchange) es un
código de 7 bits originalmente diseñado en la década de 1960 para
intercambiar texto en inglés entre sistemas.
Utiliza 128 valores posibles (2⁷) que cubren caracteres de control
(valores 0–31), puntuación, dígitos (‘0’–‘9’), letras mayúsculas
(‘A’–‘Z’), minúsculas (‘a’–‘z’) y algunos símbolos especiales.
Estructura de 7 bits
Rango: 0 … 127 (decimal).
La primera mitad (0–31) se reserva para caracteres de control
(NUL, SOH, STX, …, LF, CR, etc.). Estos no imprimen símbolos, sino
que controlan acciones (p. ej., salto de línea).
La segunda mitad (32–126) contiene caracteres imprimibles:
o 32 (espacio), 33 (‘!’), …, 47 (‘/’), 48–57 (‘0’–‘9’), 65–90 (‘A’–‘Z’),
97–122 (‘a’–‘z’), 123–126 (‘{’, ‘|’, ‘}’, ‘~’).
o 127 (DEL) también era un carácter de control.
ASCII extendido de 8 bits
Para cubrir símbolos adicionales (acentos, letras de otros idiomas,
caracteres gráficos), se implementó una extensión que utiliza 8 bits
(valores 0–255).
Los 128 valores (0–127) coinciden con el ASCII estándar.
Los valores 128–255 (llamados “extended ASCII”) varían según la
página de códigos (p. ej., Latin-1, CP437). Incluyen caracteres latinos
con acentos (é, ñ, ç), símbolos especiales (árboles, cuadros), etc.
Ejemplo de tabla parcial ASCII 7 bits:
BINARI DECIM CARÁCT
DESCRIPCIÓN
O AL ER
0100000
65 ‘A’ Letra mayúscula A
1
0110000
97 ‘a’ Letra minúscula a
1
0011000
48 ‘0’ Dígito cero
0
0010000
32 (esp) Espacio
0
0000101 Line Feed (salto de
10 LF
0 línea)
0111111
127 DEL Carácter de borrado
1
Limitaciones
Solo cubre idiomas basados en el alfabeto latino sin acentos en la
versión de 7 bits.
La versión extendida de 8 bits depende de la página de códigos, lo
que causa incompatibilidades si no se usa el mismo estándar en
emisor y receptor.
5.2 Código Unicode: principio, planes y puntos de código
Para ofrecer cobertura global de todos los caracteres de todos los idiomas y
símbolos técnicos, se creó Unicode.
Principios clave
Punto de código (code point): Cada carácter recibe un valor
numérico único (U+0000 … U+10FFFF).
Planes de Unicode: El espacio de puntos de código se organiza en
“planos” de 65 536 (2¹⁶) valores cada uno.
o Plano Multilingüe Básico (BMP, Basic Multilingual Plane):
U+0000 … U+FFFF (cubren caracteres latinos, griegos, cirílicos,
símbolos básicos).
o Planos suplementarios:
Plano 1 (SMP, Suplemental Multilingual Plane) para
símbolos históricos, emojis, sistemas de escritura
antiguos.
Planos 2–16 para planes suplementarios de uso
especializado: símbolo astronómico, música, ideogramas
chinos extendidos, etc.
Estructura de Unicode
Cada carácter tiene un identificador del tipo “U+XXXX”
(hexadecimal).
Ejemplo:
o ‘A’ = U+0041
o ‘ñ’ = U+00F1
o ‘中’ = U+4E2D
o Emoji ‘😃’ = U+1F603
Ventajas
Permite codificar todos los sistemas de escritura del mundo en un
solo estándar.
Evita problemas de incompatibilidad de páginas de códigos.
Facilita la interoperabilidad y renderizado correcto en aplicaciones
multilingües.
5.3 Formatos de codificación Unicode: UTF-8, UTF-16, UTF-32
Unicode define puntos de código, pero el almacenamiento real en bytes se
realiza con codificaciones que traducen esos puntos a secuencias de
bytes. Las más comunes son UTF-8, UTF-16 y UTF-32:
5.3.1 UTF-8 (Variable, 1–4 bytes)
Características:
o Codifica cada punto de código en 1 a 4 bytes.
o Compatible hacia atrás con ASCII: los valores U+0000 …
U+007F se codifican en un solo byte idéntico a su valor ASCII
(0–127).
o Los valores U+0080 … U+07FF usan 2 bytes; U+0800 …
U+FFFF usan 3 bytes; U+10000 … U+10FFFF usan 4 bytes.
Estructura (resumen):
o 0xxxxxxx → caracteres ASCII (1 byte).
o 110xxxxx 10xxxxxx → puntos de código de 2 bytes.
o 1110xxxx 10xxxxxx 10xxxxxx → puntos de código de 3 bytes.
o 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx → puntos de código de
4 bytes.
Ventajas:
o Eficiente para texto predominantemente en ASCII (lenguajes
occidentales).
o Permite concatenar y buscar sin repetidamente verificar
alineación de 2 bytes.
o Estándar de facto en web, muchos sistemas operativos y
lenguajes de programación.
5.3.2 UTF-16 (Variable, 2 u 4 bytes)
Características:
o Emplea “surrogate pairs” para codificar puntos de código
fuera del BMP.
o Para U+0000 … U+FFFF (BMP), cada punto codificado en 2
bytes (16 bits).
o Para U+10000 … U+10FFFF, utiliza pares de 16 bits (4 bytes en
total).
Surrogate Pairs:
o Rango U+D800 … U+DBFF: “surrogates altos”.
o Rango U+DC00 … U+DFFF: “surrogates bajos”.
o Para codificar un carácter fuera del BMP:
vbnet
Código' = punto de código – 0x10000
Surrogate alto = 0xD800 + ((Código' >> 10) & 0x3FF)
Surrogate bajo = 0xDC00 + (Código' & 0x3FF)
Ventajas:
o Moderada eficiencia en texto con muchos caracteres fuera del
ASCII, pero no tanto como UTF-8 para texto europeo.
o Usado internamente en algunas plataformas como Windows
(UTF-16 “little endian”).
5.3.3 UTF-32 (Fijo, 4 bytes)
Características:
o Cada punto de código ocupa exactamente 4 bytes (32 bits).
o Codificación trivial: valor de punto de código = valor de 32 bits.
Ventajas:
o Acceso directo a cada carácter sin cálculos de desplazamiento.
o Útil en algoritmos que procesan texto en forma de arrays de
“palabras” de 32 bits.
Desventajas:
o Despilfarro de memoria, ya que incluso caracteres ASCII usan 4
bytes.
5.4 Ventajas y usos de cada codificación en entornos multilingües
UTF-8:
o Ventajas:
Compatibilidad total con ASCII, sin bytes nulos en texto
ASCII.
El más extendido en web, bases de datos y protocolos de
red.
Eficiente en espacio cuando el texto usa principalmente
caracteres ASCII (por ejemplo, inglés).
o Usos:
Páginas web (HTML, XML).
Protocolos de red (HTTP, SMTP).
Almacenamiento de archivos de texto en sistemas
UNIX/Linux y muchos editores de texto.
UTF-16:
o Ventajas:
Menor espacio que UTF-8 para textos con muchos
caracteres del BMP (por ej., idiomas asiáticos).
Permite indexar carácter a carácter de manera más
directa (excepto para surrogate pairs).
o Usos:
Interno en sistemas Windows (API Win32).
Almacenamiento en formatos binarios de lenguajes
como Java (cadenas char[]).
Documentos multimedia (XML, JSON) en algunas
aplicaciones.
UTF-32:
o Ventajas:
Representación de longitud fija: un carácter = 4 bytes.
Simplifica algoritmos de manipulación de texto sin
preocuparse por longitudes variables.
o Usos:
Aplicaciones que requieren acceso rápido e indexación
directa de caracteres (procesamiento de texto intensivo).
Internamente en ciertos motores o bibliotecas de
manipulación de texto.
En entornos multilingües, se prefiere:
UTF-8 para máxima compatibilidad y ahorro de espacio en textos
occidentales, con amplia adopción en la web.
UTF-16 cuando la mayoría del contenido pertenece al BMP y se
necesita manipulación ágil de arreglos de 16 bits.
UTF-32 en casos muy específicos donde la simplicidad de índices
fijos justifique el mayor consumo de memoria.
6. Representación de datos gráficos y multimedia
La información gráfica (imágenes, audio, vídeo) se codifica de modo
diferente al texto: se basa en muestreo, cuantificación y, en muchos
casos, compresión (sin pérdida o con pérdida) para optimizar el espacio.
6.1 Imágenes estáticas
6.1.1 Mapas de bits (BMP, RAW): resolución, profundidad de color
(1, 8, 24 bits)
Mapas de bits (bitmaps) almacenan la imagen como una malla de
píxeles. Cada píxel codifica un color mediante uno o varios bytes,
según la profundidad de color (bits por píxel, bpp).
Profundidad de color: determina cuántos colores distintos puede
mostrar la imagen:
o 1 bit: 2 colores (blanco y negro).
o 8 bits: 256 colores (se define una paleta de 256 colores).
o 24 bits: 16 777 216 colores (RGB verdadero, 8 bits por canal;
R,G,B = 0–255).
o También existe 32 bpp que añade canal alfa para
transparencia.
Formato BMP (Bitmap Windows):
o Estructura muy sencilla, sin compresión (o con compresión RLE
opcional).
o Cabecera: tamaño del archivo, dimensiones, profundidad de
color.
o Datos de píxeles: fila por fila, de abajo a arriba (histórico);
cada píxel ocupa bpp bits.
Formato RAW:
o Simple volcado de valores de píxel, sin encabezados ni
metadatos.
o Útil en cámaras digitales o aplicaciones especializadas;
requiere conocer la resolución y profundidad a priori.
Conceptos:
Resolución: dimensiones en píxeles (ancho × alto).
Profundidad de color: bits usados para cada píxel.
Tamaño en bytes: ancho × alto × (bpp/8).
6.1.2 Paletas y compresión sin pérdida (PNG, GIF)
Paletas:
o En imágenes indexed color (8 bpp o menos), cada píxel
almacena un índice a una paleta (tabla con colores RGB).
o Permite reducir el número de bits por píxel para imágenes con
menos colores (ilustraciones, logotipos).
PNG (Portable Network Graphics):
o Algoritmo de compresión sin pérdida basado en Deflate
(similar a ZIP).
o Puede manejar imágenes de 8 o 24 bpp, además de soporte
alfa (canal transparencia).
o Incluye filtros por línea antes de la compresión para mejorar la
eficiencia.
GIF (Graphics Interchange Format):
o Usa compresión sin pérdida LZW (Lempel–Ziv–Welch).
o Soporta paleta de hasta 256 colores (8 bpp).
o Permite animaciones simples (GIF animado) y transparencia
binaria (un solo color transparente).
Comparativa:
PNG: mejor para fotografías o imágenes con degradados suaves, sin
pérdida de calidad.
GIF: útil para gráficos sencillos, animaciones cortas, limitaciones de
color.
6.1.3 Compresión con pérdida (JPEG): muestreo cromático, DCT
JPEG (Joint Photographic Experts Group): estándar de
compresión con pérdida para imágenes fotográficas.
Pasos principales:
1. Separar canales: se convierte de RGB a espacio YCbCr
(luminancia Y y dos crominancias Cb, Cr).
2. Muestreo cromático (Chroma Subsampling): se reduce
resolución de canales de color (p. ej., [Link], [Link]) porque el ojo
humano es menos sensible a detalles de color que a
luminancia.
3. Dividir en bloques de 8×8 píxeles.
4. Para cada bloque, aplicar la Transformada Discreta de
Coseno (DCT) para pasar de dominio espacial a frecuencia.
5. Cuantificación: dividir coeficientes DCT por una matriz de
cuantificación y redondear al entero más cercano; aquí se
introduce pérdida.
6. Codificación (entropía): aplicar Huffman o aritmética para
codificar los coeficientes cuantificados.
Rendimiento:
o Alta eficiencia para fotografías con gradientes suaves.
o Pérdida de calidad visible si la compresión es muy agresiva
(artefactos en bloques de 8×8).
o Soporta diferentes calidades/ratios de compresión según matriz
de cuantificación.
6.2 Audio digital
6.2.1 Muestreo y cuantificación (frecuencia, bits de muestreo)
Muestreo (sampling): proceso de medir la amplitud de una señal
analógica (sonido) a intervalos regulares de tiempo.
o Frecuencia de muestreo (sampling rate): número de
muestras por segundo (Hz).
Estándar CD: 44 100 Hz (44,1 kHz).
Audio profesional: 48 kHz, 96 kHz, 192 kHz.
Cuantificación (quantization): asignar cada muestra analógica a
un valor discreto (binario).
o Bits de muestreo (bit depth): determina la resolución de
amplitud (por ejemplo, 16 bits → 65 536 niveles; 24 bits → ~16
millones de niveles).
Teorema de Nyquist–Shannon: para reconstruir sin pérdida una señal
analógica, la frecuencia de muestreo debe ser al menos el doble de la
máxima frecuencia de interés.
6.2.2 PCM (Pulse Code Modulation)
PCM es el método más común para codificar audio sin comprimir.
o Cada muestra cuantificada se almacena en un número fijo de
bits (16, 24 o 32 bits).
o Formato de archivo WAV (Windows) y AIFF (Apple) suelen
contener PCM sin compresión.
Formato típico de WAV:
o Cabecera RIFF: metadatos del archivo, frecuencia de
muestreo, canales, bits de muestreo.
o Datos de audio: muestras PCM interleaved si son múltiples
canales.
6.2.3 Compresión con pérdida (MP3, AAC) y sin pérdida (FLAC)
Compresión sin pérdida: reduce el tamaño sin descartar
información.
o FLAC (Free Lossless Audio Codec): compresión mediante
predicción linear y codificación entropía.
o Ventaja: la reconstrucción es exacta; el archivo se puede usar
en edición profesional.
o Ratio de compresión típico: 30–50 % de tamaño original.
Compresión con pérdida: elimina información poco perceptible
para el oído.
o MP3 (MPEG-1 Audio Layer III): utiliza psicoacústica para
descartar frecuencias inaudibles, luego codifica con Huffman y
MDCT/DCT.
o AAC (Advanced Audio Coding): sucesor de MP3, mejor
eficiencia y calidad a igual tasa de bits.
o Ratio: 10–12× menor que PCM, con calidad aceptable (128–320
kbps).
6.3 Vídeo digital
El vídeo digital combina secuencias de imágenes (fotogramas, “frames”)
con audio y metadatos de sincronización. La representación abarca tanto la
codificación de cada cuadro como técnicas de compresión para reducir
drásticamente el tamaño.
6.3.1 Secuencia de imágenes (frames) y frecuencia de muestreo
(fps)
Frame: cada imagen en la secuencia que, reproducida a cierta
velocidad, genera la ilusión de movimiento.
Frecuencia de muestreo de vídeo (fps): número de frames por
segundo.
o Estándares típicos: 24 fps (cine), 25 fps (PAL), 30 fps (NTSC),
50/60 fps (deportes, alta fluidez).
Resolución: número de píxeles horizontales × verticales por frame
(ej., 1920×1080 = Full HD).
Profundidad de color: bits por píxel; 24 bits (8 bits por canal RGB)
es común.
6.3.2 Códecs y estándares (MPEG-2, H.264, H.265): GOP, I-P-B
frames
Para reducir el tamaño de vídeo sin pérdida drástica de calidad, se emplean
códecs basados en compresión temporal y espacial:
1. Códecs clásicos (MPEG-2):
o Utilizado en DVD y transmisión de TV digital.
o Organiza los frames en Group of Pictures (GOP): secuencia
de frames que combina fotogramas completos y diferencias.
o Tipos de frames:
I-frames (Intra-coded): completos, sin referencia a
otros frames (similar a JPEG).
P-frames (Predictive): codifican diferencias respecto a
un frame anterior (I o P).
B-frames (Bidirectional): utilizan información de
frames anterior y posterior para codificarse (mayor
compresión).
2. MPEG-4/H.264 (AVC):
o Mayor eficiencia que MPEG-2: mejor compresión manteniendo
calidad.
o Bloques de codificación en macroblocks de 16×16 píxeles.
o Técnicas avanzadas: predicción intra-frame, movimiento inter-
frame con vectores (motion estimation), transformada DCT,
cuantificación, codificación entropía (CABAC/CAVLC).
o Soporta perfiles y niveles (Baseline, Main, High) según
complejidad y uso (streaming, Blu-ray).
3. H.265 (HEVC, High Efficiency Video Coding):
o Generación posterior a H.264: aproximadamente el doble de
compresión para la misma calidad de imagen.
o Utiliza Coding Tree Units (CTU) en lugar de macroblocks:
bloques más grandes y particionamiento más flexible.
o Mejora en predicción de movimiento y compresión de
transformada.
o Soporta resoluciones UHD (4K, 8K).
Flujo de compresión de vídeo (resumen):
1. Dividir cada frame en bloques/macroblocks.
2. Predicción intra (dentro del mismo frame) o inter (entre frames).
3. Calcular residuos (diferencias), aplicar transformada (DCT o
equivalente).
4. Cuantificación (introduce pérdida).
5. Codificación de entropía (Huffman, CABAC).
6. Crear GOP según tipo de frame.
7. Agrupación y estructuras básicas en memoria
7.1 Byte, palabra, doble palabra: alineación y direccionamiento
Byte: unidad mínima de almacenamiento direccionable, típicamente
8 bits.
o Cada byte tiene una dirección única en memoria (por ejemplo,
0x0000₁₆, 0x0001₁₆, …).
o Con N bytes de dirección de k bits, se pueden direccionar 2ᵏ
bytes.
Palabra (word): conjunto de bytes que la CPU maneja como unidad
atómica para instrucciones y operaciones.
o Su tamaño depende de la arquitectura:
16 bits (2 bytes) en arquitecturas antiguas (x86 real
mode).
32 bits (4 bytes) en arquitecturas de 32 bits.
64 bits (8 bytes) en arquitecturas de 64 bits (x86-64).
o Muchas instrucciones leen/escriben palabras completas (por
ejemplo, cargar un registro de 32 bits con un solo acceso).
Doble palabra (double word, dword): el doble de una palabra.
o En un sistema de 32 bits, una dword = 64 bits (8 bytes).
o En un sistema de 64 bits, una dword = 128 bits (16 bytes),
aunque el término se usa con menor frecuencia.
Alineación (alignment):
o Se refiere a cómo se sitúan los datos en direcciones de
memoria que sean múltiplos de su tamaño natural. Por
ejemplo:
Un entero de 4 bytes generalmente se coloca en una
dirección múltiplo de 4 (0x...00, 0x...04, 0x...08…).
Una palabra de 2 bytes se alinea en direcciones pares
(múltiplos de 2).
o Ventajas de la alineación:
Acceso más rápido: la CPU puede leer/escribir en un solo
ciclo de memoria.
Manejo más eficiente del caché y del bus.
o Desventajas de la falta de alineación (misaligned access):
Puede requerir dos accesos de memoria para recuperar
el dato completo.
En algunas arquitecturas genera excepción de alineación
o penaliza en rendimiento.
Direccionamiento:
o La memoria se conceptualiza como un gran array de bytes con
direcciones consecutivas.
o Cuando se accede a un dato que ocupa varios bytes (por
ejemplo, una palabra de 4 bytes), el sistema lee a partir de la
dirección base y recupera los bytes contiguos en orden según
la “endianness” (ver apartado 7.2).
o Ejemplo (32 bits):
Dirección 0x1000₁₆ = byte0
0x1001₁₆ = byte1
0x1002₁₆ = byte2
0x1003₁₆ = byte3
Si alineado, una palabra (4 bytes) en 0x1000₁₆ contendrá
esos 4 bytes.
7.2 Endianess: Big Endian vs Little Endian y su repercusión en
intercambio de datos
Cuando un valor de varios bytes se almacena en memoria, existe una
convención para el orden de esos bytes:
Big Endian (gran orden): el byte más significativo (MSB) se
almacena en la dirección de memoria más baja.
o Ejemplo: valor 0x12345678 (32 bits).
Dirección 0x1000₁₆ → 0x12
Dirección 0x1001₁₆ → 0x34
Dirección 0x1002₁₆ → 0x56
Dirección 0x1003₁₆ → 0x78
Little Endian (pequeño orden): el byte menos significativo (LSB) se
almacena en la dirección más baja.
o Mismo valor 0x12345678:
Dirección 0x1000₁₆ → 0x78
Dirección 0x1001₁₆ → 0x56
Dirección 0x1002₁₆ → 0x34
Dirección 0x1003₁₆ → 0x12
Repercusión en intercambio de datos:
Al transferir datos entre sistemas con distinta endianess (por ejemplo,
entre un procesador x86 – que es Little Endian – y otro PowerPC – que
es Big Endian –), es necesario “swapear” el orden de los bytes para
que el valor se interprete correctamente.
Protocolos de red (por ejemplo, TCP/IP) definen el “network byte
order” en Big Endian, por lo que máquinas Little Endian deben
convertir a Big Endian antes de enviar.
Ejemplo práctico:
Al almacenar el entero decimal 305419896₁₀ = 0x12345678 en un
archivo binario,
o Big Endian escribirá: 12 34 56 78
o Little Endian escribirá: 78 56 34 12
Un programa que lee el archivo debe conocer la endianess usada o
interpretará datos incorrectos.
7.3 Estructuras de datos elementales: arrays, registros y cómo se
almacenan en memoria
Arrays (arreglos)
Un array es una colección homogénea de elementos contiguos en
memoria.
Si cada elemento ocupa N bytes y el array tiene M elementos, su
tamaño total es M × N bytes.
El elemento[i] se almacena en dirección:
css
dirección_base + (i × N)
Ejemplo:
o Array de 10 enteros de 4 bytes (int32) alineados a 4 bytes:
Dirección del elemento 0 = base.
Elemento[3] → base + (3 × 4) = base + 12.
Registros (structs)
Un registro (o struct) es una colección heterogénea de campos
(miembros), cada uno con su propio tipo y tamaño.
El orden de los campos define cómo se disponen en memoria.
En muchos compiladores se aplica relleno (padding) para mantener
la alineación de cada campo según su tamaño natural.
Ejemplo en C (suponiendo alineación por defecto en 32 bits):
c
struct Ejemplo {
char a; // 1 byte
// 3 bytes de relleno para alinear el siguiente int a dirección multiple de 4
int b; // 4 bytes
short c; // 2 bytes
// 2 bytes de relleno para alinear tamaño total a múltiplo de 4
};
o Tamaño total suele ser 8 bytes en una arquitectura de 32 bits.
Esquema de almacenamiento (direcciones relativas, offset):
sql
offset 0: a (1 byte)
offset 1..3: relleno
offset 4..7: b (4 bytes)
offset 8..9: c (2 bytes)
offset 10..11: relleno
Este comportamiento asegura que cada campo esté alineado a su tamaño
natural (por ejemplo, un int en dirección múltiplo de 4), mejorando el
rendimiento de acceso.
8. Codificación de canal y corrección de errores
Cuando los datos se almacenan o transmiten, es posible que ocurran errores
(ruido en señales, bits volteados). Para detectar y, en algunos casos,
corregir errores, se implementan códigos de detección y corrección. A
continuación, se describen los más didácticos y utilizados.
8.1 Bits de paridad (par/impar) para detección simple de errores
Concepto: se añade un bit extra (bit de paridad) a cada unidad de
datos (por ejemplo, un byte) para que el número total de bits a 1 sea
par (paridad par) o impar (paridad impar).
Cálculo de paridad:
o Paridad par: el bit de paridad se elige para que, contando
todos los bits (incluido él), el total sea un número par.
o Paridad impar: el bit de paridad se elige para que la suma
total de bits a 1 sea impar.
Ejemplo (byte + bit de paridad, paridad par):
Byte original: 10110010₂ (cuatro bits a 1).
Ya hay un conteo par (4), así que el bit de paridad debe ser 0 → se
envía 10110010 0₂.
Si hubiera 3 bits a 1 (conteo impar), el bit de paridad se pondría a 1 →
…1₂ para que al sumarse a 3 dé 4 (par).
Detección:
En recepción se vuelve a contar el número de bits a 1.
Si no coincide con la paridad esperada, se detecta un error.
Limitación: solo detecta errores de número impar de bits cambiados;
no puede indicar cuál bit está dañado, ni corregirlo.
8.2 Códigos de Hamming para detección y corrección de errores
simples
Código de Hamming: permite no solo detectar sino corregir errores
de un solo bit en un bloque de datos.
Introduce varios bits de paridad distribuidos en posiciones específicas
de la secuencia.
Principio básico:
Para un bloque de datos de k bits, se añaden r bits de paridad, de
modo que:
2^r ≥ k + r + 1
Esto asegura que con r bits de paridad se pueden cubrir todas las posiciones
(k datos + r paridad + 1 posición de “sin error”).
Se numeran todas las posiciones (1, 2, 3, …, k + r). Las potencias de
2 (1, 2, 4, 8,…) se reservan para bits de paridad.
Cada bit de paridad cubre un subconjunto de posiciones cuya
representación binaria tiene ‘1’ en el bit correspondiente.
Ejemplo con 4 bits de datos (k=4) y r=3 bits de paridad:
Queremos enviar D = d₁ d₂ d₃ d₄. Se crean 7 posiciones totales
(posiciones 1–7):
o P₁ en posición 1, P₂ en posición 2, D₁ en 3, P₃ en 4, D₂ en 5, D₃
en 6, D₄ en 7.
Cada paridad Pᵢ comprueba un conjunto:
o P₁ cubre posiciones con bit menos significativo (LSb) = 1 ([Link].,
pos 1,3,5,7…).
o P₂ cubre posiciones con segundo bit = 1 (pos 2,3,6,7…).
o P₃ cubre posiciones con tercer bit = 1 (pos 4,5,6,7…).
El valor de cada Pᵢ se calcula para que la suma total de bits 1 en su
conjunto sea par (o impar, según convención).
Detección y corrección:
Al recibir, se recalculan los bits de paridad (Comprobación de
Sindrome).
El síndrome es la concatenación de resultados de cada bit de
paridad recalculado (por ejemplo, 3 bits = valor 0 a 7).
o Si síndrome = 000₂ → no hay error.
o Si síndrome ≠ 000₂ → indica la posición (en decimal) del bit
erróneo ([Link]., síndrome = 011₂ = 3 → bit 3 está mal).
Se invierte el bit en esa posición para corregir el error.
8.3 Códigos CRC (Cyclic Redundancy Check) para detección de
errores en redes
El CRC es una técnica de detección de errores ampliamente usada en redes,
discos y protocolos digitales, que considera el bloque de datos como un
polinomio en GF(2).
Principio básico:
Se elige un polinomio generador G(x) de grado r (por ejemplo, CRC-
32 usa un polinomio de grado 32).
Al transmitir un mensaje de bits M (de longitud m bits), se calcula
M(x) · xʳ mod G(x), que da un residuo R(x) de grado < r.
Se envía M seguido de los r bits de R (CRC).
En recepción, se toma todo el bloque (M concat R) y se calcula
(M(x)·xʳ + R(x)) mod G(x). Si el resultado es 0, se considera que no
hay error (o al menos ningún patrón de error detectado).
Ventajas:
Capaz de detectar ráfagas de errores de longitud ≤ r, y la mayoría de
ráfagas más largas.
Muy eficiente implementado en hardware (con registros de
desplazamiento y XOR).
Ejemplo en CRC-16:
Polinomio generador: G(x) = x¹⁶ + x¹⁵ + x² + 1 (0x8005).
Transmisor:
1. Representar datos como polinomio M(x).
2. Calcular residuo R(x) = M(x)·x¹⁶ mod G(x).
3. Concatenar bits de R con M.
Receptor:
1. Recibe bits totales (M concat R).
2. Calcula residuo S(x) mod G(x).
3. Si S(x) = 0 → mensaje aceptado; else → error detectado.
Aplicaciones: Ethernet (CRC-32), PPP (CRC-16), formatos de
almacenamiento (ZIP, PNG),…
9. Representación y compresión
En el entorno informático, almacenar o transmitir grandes volúmenes de
datos (imágenes, audio, texto, vídeo) sin optimización supondría un uso
excesivo de espacio y ancho de banda. Por ello, se emplean técnicas de
compresión, que reducen el tamaño de los datos manteniendo, según el
caso, la integridad total (compresión sin pérdida) o renunciando a algún
detalle imperceptible (compresión con pérdida).
9.1 Principios de compresión sin pérdida (Run-Length, LZW)
9.1.1 Run-Length Encoding (RLE)
Principio básico
RLE es una técnica muy simple: encuentra “corridas” o secuencias
consecutivas del mismo símbolo y las sustituye por un par (valor,
longitud).
Ejemplo práctico en imágenes en blanco y negro:
o Supongamos una fila de píxeles:
11111000111
o RLE la codificaría como (1,5), (0,3), (1,3).
o En binario real, si 1 = blanco y 0 = negro, podría almacenarse
“5 blancos, 3 negros, 3 blancos.”
Ventajas
Muy eficaz cuando hay largas secuencias repetidas (p. ej., imágenes
escaneadas de documentos, mapas de bits monocromos, ciertos
formatos de fax).
Implementación extremadamente sencilla, que puede realizarse en
tiempo lineal.
Inconvenientes
Si las secuencias repetidas son cortas o inexistentes (imágenes
fotográficas, datos aleatorios), el resultado puede ocupar igual o
incluso más espacio que los datos originales.
Normalmente se combina con otros métodos o se aplica solo a partes
específicas (ej. compresión de datos de paleta en PNG).
9.1.2 LZW (Lempel–Ziv–Welch)
Principio básico
LZW es un método de compresión sin pérdida basado en la
construcción dinámica de un diccionario de cadenas de datos vistas
en el flujo de entrada.
Empieza con un diccionario que contiene todos los posibles símbolos
elementales (por ejemplo, todos los bytes 0–255).
A medida que avanza por la secuencia de entrada, detecta la cadena
más larga que está en el diccionario y la sustituye por su código. A
continuación, añade al diccionario la concatenación de esa cadena
con el siguiente símbolo leído.
Así, el diccionario crece y “aprende” patrones repetidos.
Funcionamiento simplificado
1. Inicializar el diccionario con todos los símbolos de un byte (0–255).
2. Leer el primer símbolo σ y colocarlo en la variable “cadena actual” C.
3. Leer el siguiente símbolo σ′; si C+σ′ está en el diccionario, concatenar
(C = C+σ′) y continuar leyendo.
4. Si C+σ′ no existe en el diccionario, emitir el código de C, insertar
(C+σ′) en el diccionario con el siguiente código libre, y reiniciar C = σ
′.
5. Repetir hasta final de datos; al final, emitir el código de C.
Ventajas
Generalmente consigue ratios de compresión muy superiores a RLE
en datos con redundancias intermedias y patrones de bytes repetidos
(por ejemplo, texto, imágenes GIF).
No requiere enviar el diccionario, pues tanto compresor como
descompresor inician con el mismo conjunto inicial y generan
idénticos diccionarios en paralelo.
Se utiliza en formatos populares como GIF, TIFF y el algoritmo de
compresión interno de PDF.
Inconvenientes
Los diccionarios pueden crecer mucho, por lo que se definen tamaños
máximos de código (p. ej., 12 bits, 16 bits). Cuando el diccionario se
llena, se puede reiniciar o dejar de añadir nuevas entradas.
Menos eficaz si los datos tienen baja redundancia o patrones muy
variables (por ejemplo, datos cifrados o imágenes fotográficas en
crudo).
9.2 Principios de compresión con pérdida aplicada a imágenes
(JPEG) y audio (MP3)
La compresión con pérdida se basa en eliminar información menos relevante
o imperceptible para el usuario, obteniendo ratios de reducción mucho más
altos que los métodos sin pérdida, a cambio de una degradación controlada
en la calidad.
9.2.1 Compresión con pérdida en imágenes – JPEG
Flujo de compresión en JPEG
1. Conversión de espacio de color
o Originalmente en RGB, se convierte a YCbCr (luminancia y dos
componentes de crominancia).
o El ojo humano es más sensible a cambios en luminancia que en
crominancia, por lo que la compresión se centrará en reducir
datos de color.
2. Muestreo cromático (Chroma Subsampling)
o Se reduce la resolución de los canales Cb y Cr (por ejemplo,
formato [Link] o [Link]).
o Permite agrupar cada 2×2 píxeles en un único valor de
crominancia, reduciendo el volumen sin degradar
perceptiblemente la calidad.
3. División en bloques de 8×8 píxeles
o Cada bloque de 8×8 en Y, Cb, Cr se procesa por separado.
4. Transformada Discreta de Coseno (DCT)
o A cada bloque de 8×8 se le aplica DCT para pasar de dominio
espacial (píxeles) a dominio de frecuencia (coeficientes DCT).
o El coeficiente [0,0] representa la componente de frecuencia
baja (DC), los coeficientes restantes representan armonías
crecientes.
5. Cuantificación
o Cada coeficiente DCT se divide entre un valor en una matriz de
cuantificación ajustable según el nivel de calidad deseado (por
ejemplo, mayor calidad → valores de cuantificación más bajos).
o Este paso introduce pérdida porque se redondean los
resultados.
o P. ej., un coeficiente de 123 se divide por 16 → 7.6875 → se
redondea a 8.
6. Codificación de entropía
o Los coeficientes cuantificados, mayormente ceros en
frecuencias altas, se ordenan en zigzag y se codifican usando
Huffman o codificación aritmética.
o Se genera la secuencia de bits comprimidos que representa
cada bloque.
7. Agrupación en frames y contenedores
o Se pueden agrupar múltiples bloques en segmentos JPEG, y
luego encapsular en contenedores (por ejemplo, JFIF o EXIF con
metadatos de tamaño, resolución, perfil de color).
Efectos y artefactos
Cuando la compresión es agresiva, aparecen artefactos de bloque
(cuadrículas de 8×8), pérdida de nitidez y “anillos” alrededor de
bordes de alto contraste.
A tasas de compresión moderadas (p. ej., calidad 80–90/100), la
pérdida es casi imperceptible.
9.2.2 Compresión con pérdida en audio – MP3
Flujo de compresión en MP3
1. Segmentación en marcos (frames)
o El flujo de audio digital (PCM) se divide en marcos de unos
milisegundos (p. ej., 1152 muestras en MP3).
2. Análisis de subbandas y MDCT (Modified Discrete Cosine
Transform)
o Cada marco se divide en subbandas de frecuencia y se aplica
MDCT para pasar a dominio de frecuencia.
o Esto permite analizar la energía en cada rango de frecuencia.
3. Modelo psicoacústico
o MP3 utiliza un modelo psicoacústico para determinar qué
componentes de frecuencia son perceptibles o enmascarados
por otras frecuencias cercanas.
o Componentes enmascarados o muy por encima del umbral de
audición se pueden descartar o cuantificar con mayor error sin
que resulte perceptible.
4. Cuantificación y codificación
o Los coeficientes de frecuencia se cuantifican con distintos
niveles de detalle según la relevancia psicoacústica.
o Se agrupan en “grupos de asignación de bits” para cumplir con
la tasa de bits deseada (p. ej., 128 kb/s).
o Finalmente, se aplica codificación de entropía (Huffman) para
comprimir las secuencias.
5. Empaquetado en frames MP3
o Cada frame comprimido incluye cabecera con metadatos (tasa
de bits, frecuencia de muestreo, canal).
o Al concatenar frames, se genera el archivo MP3 completo.
Efectos y artefactos
A bajas tasas (p. ej., 64 kb/s), se producen artefactos audibles como
“swirl” o distorsiones en frecuencias altas.
A tasas medias (128–192 kb/s), la mayoría de usuarios percibe sonido
casi indistinguible de una fuente PCM original.
9.3 Ventajas e inconvenientes de cada método en almacenamiento
y transmisión
9.3.1 Compresión sin pérdida
Ventajas
Integridad total: el dato original se puede reconstruir exactamente
sin pérdida alguna.
Versatilidad: se puede usar en documentos de texto, bases de
datos, imágenes técnicas, archivos de código fuente y entornos
donde cada bit importa (por ejemplo, archivos ejecutables, bases de
datos).
Simplicidad de implementación: algoritmos como RLE o LZW son
relativamente fáciles de integrar y decodificar.
Inconvenientes
Ratios de compresión limitados: en datos ya muy aleatorios o sin
redundancia clara, la reducción de tamaño es escasa.
Procesamiento: en el caso de LZW, implica uso de memoria para el
diccionario; en grandes archivos puede ser costoso en recursos.
9.3.2 Compresión con pérdida
Ventajas
Ratios de compresión muy altos: en audio y vídeo permite reducir
10× o más el tamaño manteniendo calidad aceptable.
Uso en streaming: facilita transmisión en redes con ancho de banda
limitado (radio en línea, streaming de vídeo).
Control de calidad: se puede ajustar la configuración (calidad JPEG,
tasa de bits MP3) según requisitos exactos (p. ej., ahorrar espacio vs.
mantener fidelidad).
Inconvenientes
Pérdida irreversible: la información descartada no puede
recuperarse; si se sigue recodificando sucesivamente (p. ej.,
reexportar un JPEG varias veces), la calidad se degrada
progresivamente.
Artefactos perceptibles: dependiendo del perfil y la tasa de
compresión, pueden surgir artefactos como bloques, distorsión o
pérdida de detalles sutiles.
No apto para datos críticos: no se emplea cuando es
imprescindible conservar cada bit (por ejemplo, imágenes médicas,
archivos de texto legal, bases de datos sensibles).
10. Relación con otros módulos del ciclo formativo
La representación interna de los datos es un contenido transversal que
conecta con múltiples módulos del ciclo de Sistemas y Aplicaciones
Informáticas. A continuación se describen las principales interrelaciones:
10.1 Sistemas informáticos
1. Arquitectura interna y jerarquía de memoria
o El modo en que los datos se representan (bits, bytes, palabras,
punto flotante, Unicode, etc.) incide directamente en la forma
en que la CPU, cachés y RAM acceden y gestionan la
información.
o Conocer los formatos internos permite entender por qué, por
ejemplo, un acceso mal alineado a memoria (misaligned
access) penaliza el rendimiento o incluso genera excepciones
en ciertas arquitecturas.
o La jerarquía (caché L1/L2/L3, RAM, disco) aprovecha la
localización espacial de datos (arrays contiguos, estructuras
alineadas) para optimizar accesos.
2. Buses de datos y control
o Los buses transportan secuencias de bits de anch
o o fijo (por ejemplo, 64 bits en un bus de datos). La
representación binaria de enteros, direcciones y códigos de
operación determina cuántos ciclos de bus son necesarios para
transferir un dato.
o Formatos de transferencia (por ejemplo, Big Endian vs Little
Endian en el bus, multiplexación de líneas) impactan en cómo
se interpretan las palabras enviadas.
10.2 Bases de datos
1. Tipos de datos lógicos y numéricos
o La selección de tipos de datos (INT, FLOAT, CHAR,
VARCHAR) en un SGBD se basa en la representación interna:
INT sin signo vs INT con signo (complemento a 2).
FLOAT vs DOUBLE (punto flotante simple vs doble
precisión).
o La precisión y rango que se pueden almacenar dependen del
formato interno: saber si un entero de 4 bytes permite valores
de −2³¹ a 2³¹−1 o 0 a 2³²−1 es esencial al diseñar tablas y
evitar desbordamientos.
2. Operadores booleanos en consultas
o Los operadores lógicos (AND, OR, NOT) en SQL se traducen
internamente a operaciones sobre bits:
En índices bitmap, cada fila puede representarse con un
bit 1/0, y una consulta que combine condiciones se
traduce en AND/OR a nivel de palabra de máquina.
o Conocer cómo se evalúan expresiones booleanas eficiente
(cortocircuito, orden de evaluación) ayuda a optimizar
consultas.
10.3 Lenguajes de programación y entornos de desarrollo
1. Tipos de datos primitivos y estructuras internas en memoria
o Todo lenguaje de alto nivel (C, Java, Python) define tipos
primitivos (int, float, char) que mapean a la representación
interna:
En C, un int puede corresponder a 32 bits en
complemento a 2; un float a 32 bits IEEE 754.
En Java, char es UTF-16, lo que permite representar
Unicode en 16 bits.
o Estructuras (struct en C, objetos en Java) se organizan en
memoria con alineación y relleno, acorde a lo visto en
apartados anteriores.
2. Gestión de cadenas: ASCII vs Unicode
o En aplicaciones que manejan texto, es crucial decidir si se usa
ASCII puro (7 u 8 bits) o Unicode (UTF-8, UTF-16).
o En C/C++, la función strlen() mide bytes hasta el \0 en
ASCII/UTF-8, pero en UTF-16 hay que considerar pares de bytes
y “surrogate pairs”.
o En entornos web o entornos multiplataforma, se impone UTF-8
para garantizar compatibilidad, evitando problemas de
conversión de caracteres internacionales.
10.4 Multimedia (Lenguajes de marcas y gestión de información)
1. Tratamiento de imágenes y audio en entornos web (HTML5,
CSS)
o El desarrollador web debe entender cómo el navegador
interpreta formatos binarios:
Una etiqueta <img src="[Link]"> involucra la
decodificación PNG (compresión sin pérdida), mientras
que <audio src="audio.mp3"> requiere un decodificador
MP3 (compresión con pérdida).
o En CSS, la propiedad background-image:
url(data:image/png;base64,…) codifica la imagen en Base64,
aumentando el tamaño un ~33 % frente al binario puro.
2. Formatos y códecs compatibles con navegadores y
reproductores
o Los navegadores modernos soportan JPEG, PNG, WebP para
imágenes y MP3, AAC, Opus para audio; en vídeo, H.264 (MP4),
WebM (VP8/VP9) y H.265 (HEVC en menor medida).
o Conocer sus ventajas (calidad, tamaño, licencias) y limitaciones
(navegador que lo soporte o no) es crucial para el despliegue
multimedia.
10.5 Redes e Internet
1. Representación de direcciones IP
o IPv4: 32 bits. Habitualmente se expresa en notación decimal
punteada (p. ej., [Link]), pero en memoria es un entero
de 32 bits en Big Endian (network byte order).
o IPv6: 128 bits. Se escribe en hexadecimal agrupado en 8
bloques de 16 bits (p. ej., [Link]).
En memoria se almacenan los 16 bytes en orden de red (Big
Endian).
o Convertir entre notaciones textual e interna (binario o bytes) es
necesario para operaciones de enrutamiento, máscara de
subred y checksum IP.
2. Encapsulado de datos, comprobación de errores
o En TCP/IP, cada capa agrega sus cabeceras y trailers; muchos
de estos campos (checksum IP, checksum TCP/UDP) se calculan
bit a bit para detectar errores en la transmisión.
o Ejemplo: el CRC-32 en trama Ethernet se almacena como 4
bytes al final de cada trama; el receptor lo recalcula y compara
para validar integridad.
10.6 Seguridad informática
1. Fundamentos de cifrado simétrico y asimétrico
o Los algoritmos de cifrado trabajan a nivel de bits o bloques:
Cifrado simétrico (AES) opera en bloques de 128 bits
(16 bytes), realizando sustituciones (S-boxes),
permutaciones y rondas basadas en claves.
Cifrado asimétrico (RSA) trabaja con números de
varios cientos o miles de bits, basándose en operaciones
modulares de enteros grandes.
o Conocer cómo se representan en binario y se dividen en
bloques permite entender cómo se encriptan datos arbitrarios
(texto, imágenes, archivos).
2. Hashing: operación binaria sobre datos de longitud variable
o Funciones hash (SHA-256) procesan datos en bloques de 512
bits (64 bytes), aplicando transformaciones binarias y lógicas
para producir un “resumen” de 256 bits.
o Es fundamental para almacenar contraseñas de forma segura y
para generar firmas digitales.
10.7 Implantación de sistemas operativos
1. Formateo de discos y sistemas de archivos binarios
o Al formatear un disco en FAT32, NTFS o EXT4, el sistema
operativo crea estructuras binarias (tabla de asignación de
archivos, inodos, bloques de datos).
o Entender cómo se almacenan metadatos (fechas, permisos,
punteros a bloques) en niveles de bits es esencial para
diagnósticos de integridad, recuperación tras fallos y
defragmentación.
2. Gestión de formatos de partición y direccionamiento lógico
o El MBR (Master Boot Record) en discos MBR usa los primeros
512 bytes para la tabla de particiones (4 entradas de 16 bytes
cada una), con codificación little endian en direcciones de
sector.
o En GPT (GUID Partition Table, parte de UEFI), se usa una
estructura de 128 bytes por entrada de partición, con UUIDs
almacenados en little endian y big endian según el campo.
o La conversión interna entre direcciones lógicas y físicas (LBA vs
CHS) implica manipulación directa de valores binarios.
11. Actividades prácticas para el alumnado
La siguiente batería de actividades tiene como objetivo que el alumnado
reforce de forma práctica los conceptos teóricos vistos en el resto del tema.
Cada actividad propone ejercicios que pueden hacerse a mano o bien con el
apoyo de herramientas informáticas (pseudocódigo, Python, simuladores o
software libre), fomentando tanto la comprensión manual como la
programada.
11.1 Conversión manual y programada entre sistemas de
numeración
Objetivo: Practicar la conversión de números entre decimal, binario, octal y
hexadecimal, primero realizando el proceso a mano y después
automatizándolo en un pequeño script o programa.
1. Conversión manual (a mano):
o Decimal → Binario: Utilizar divisiones sucesivas por 2 y
registrar residuos. Por ejemplo, convertir 156₁₀:
yaml
156 ÷ 2 = 78 residuo 0
78 ÷ 2 = 39 residuo 0
39 ÷ 2 = 19 residuo 1
19 ÷ 2 = 9 residuo 1
9 ÷ 2 = 4 residuo 1
4 ÷ 2 = 2 residuo 0
2 ÷ 2 = 1 residuo 0
1 ÷ 2 = 0 residuo 1
→ Leer residuos de abajo a arriba: 10011100₂.
o Binario → Octal/Hexadecimal: Agrupar bits de derecha a
izquierda en bloques de 3 (octal) o de 4 (hex). Ejemplo:
10011100₂ → para hex, (1001)(1100) → 9 C₁₆.
o Octal/Hexadecimal → Decimal: Multiplicar cada dígito por la
potencia de base correspondiente. Ejemplo: 7B₁₆ = 7·16 + 11 =
112 + 11 = 123₁₀.
2. Automatización en Python (o pseudocódigo):
o Pseudocódigo genérico:
java
Función decimal_a_binario(n):
Si n == 0: retornar "0"
cadena = ""
Mientras n > 0:
residuo = n % 2
cadena = (carácter(residuo) + cadena)
n = n // 2
Retornar cadena
Función binario_a_hexadecimal(bin_str):
// Completar al múltiplo de 4 bits
while longitud(bin_str) % 4 != 0:
bin_str = "0" + bin_str
resultado = ""
Para i desde 0 hasta longitud(bin_str)-1 en pasos de 4:
grupo = bin_str[i:i+4]
valor = valor_entero_de_binario(grupo) // 0..15
si valor < 10: dígito = carácter(valor)
sino: dígito = 'A' + (valor-10)
resultado = resultado + dígito
Retornar resultado
o Ejemplo en Python:
python
def decimal_a_binario(n):
if n == 0:
return "0"
bits = []
while n > 0:
[Link](str(n % 2))
n //= 2
return ''.join(reversed(bits))
def binario_a_hexadecimal(bin_str):
# Ajustar longitud múltiplo de 4
while len(bin_str) % 4 != 0:
bin_str = '0' + bin_str
hex_map = "0123456789ABCDEF"
result = []
for i in range(0, len(bin_str), 4):
nibble = bin_str[i:i+4]
[Link](hex_map[int(nibble, 2)])
return ''.join(result)
# Ejemplo de uso:
num = 156
b = decimal_a_binario(num) # "10011100"
h = binario_a_hexadecimal(b) # "9C"
print(f"{num}₁₀ = {b}₂ = {h}₁₆")
o Ejercicio para el alumnado: Pedir al alumno que modifique
el script para convertir de octal a decimal y de hexadecimal a
binario, completando con validación de entrada.
11.2 Diseño y simplificación de expresiones booleanas con mapas
de Karnaugh
Objetivo: Que el alumnado aprenda a simplificar funciones lógicas usando
mapas de Karnaugh (K-maps) para diseñar circuitos combinacionales más
eficientes.
1. Definir la función de verdad:
o Elegir un problema sencillo, p. ej., un semáforo con semáforo
peatonal:
Variables de entrada: P (presión de botón), T (tiempo de
paso).
Variables de salida: R (semáforo rojo para coches), G
(verde para coches), RG (verde para peatones).
o Construir la tabla de verdad con las 2² = 4 posibles
combinaciones (P, T) → (0,0), (0,1), (1,0), (1,1).
o Definir salidas según requerimientos funcionales.
2. Crear el mapa de Karnaugh:
o Para dos variables, el K-map es de 2×2. Etiquetar filas y
columnas con combinaciones Gray (00, 01, 11, 10).
o Completar con los valores de salida (1 si la función de verdad lo
indica; 0 en otro caso; puede haber “–” para términos
irrelevantes o condiciones don’t care).
3. Agrupamiento:
o Identificar grupos de 1s contiguos (de tamaño potencia de 2: 1,
2 o 4 celdas).
o Extraer términos simplificados (p. ej., un grupo que cubre dos
celdas donde P=1 y T= no importa → implica “P” en la suma de
productos).
4. Obtener la expresión mínima:
o Escribir la función simplificada usando OR de ANDs (sumas de
productos) o AND de ORs (productos de sumas), según
convenga.
5. Implementación con puertas lógicas (opcional):
o Dibujar el diagrama de puertas según la expresión reducida.
Ejercicio propuesto:
Plantear distintas funciones (ej., un comparador de 2 bits, un
sumador de uno) y pedir que simplifiquen con K-maps de 3 o 4
variables.
Evaluar resultados comparando la expresión mínima con la original.
11.3 Implementación de operaciones binarias (suma/resta en
complemento a 2) en pseudocódigo o Python
Objetivo: Que el alumno entienda cómo operan las sumas y restas en
complemento a 2, y que pueda codificarlas en pseudocódigo o Python.
1. Suma de enteros en complemento a 2 (N bits):
o Representar los operandos como enteros Python limitados a N
bits (aplicar máscara & ((1 << N) - 1) para truncar).
o Realizar la suma entera normal.
o Detectar overflow: si al sumar dos números con el mismo signo
de entrada aparece un signo distinto en el resultado (bit N-1),
overflow.
o Aplicar máscara final: resultado = (a + b) & ((1 << N) - 1).
Ejemplo en Python para 8 bits:
python
N=8
MASK = (1 << N) - 1 # 0xFF
SIGN_BIT = 1 << (N - 1)
def complement2_to_int(x):
# Interpreta x como entero con signo en complemento a 2 (N bits)
if x & SIGN_BIT:
return x - (1 << N)
return x
def suma_complemento2(a, b):
# a y b ya deben ser valores en 0..255 que representan complemento a 2
s = (a + b) & MASK
# Detectar overflow (opcional)
sa, sb, ss = a & SIGN_BIT, b & SIGN_BIT, s & SIGN_BIT
overflow = (sa == sb) and (ss != sa)
return s, overflow
# Ejemplo: sumar +120 y +20
a = 120 & MASK
b = 20 & MASK
resultado, ovf = suma_complemento2(a, b)
print("Raw binario:", format(resultado, "08b"))
print("Como entero con signo:", complement2_to_int(resultado), "Overflow:",
ovf)
2. Resta usando complemento a 2:
o Para restar a – b, basta obtener complemento a 2 de b e
invocarlo como suma:
python
b_neg = ((~b) + 1) & MASK
resultado, ovf = suma_complemento2(a, b_neg)
3. Pseudocódigo general:
java
función entero_con_signo(valor, N):
max_valor = 1 << N
signo_mask = 1 << (N - 1)
if valor & signo_mask ≠ 0:
return valor - max_valor
return valor
función suma_binaria(a, b, N):
máscara = (1 << N) - 1
signo_mask = 1 << (N - 1)
suma = (a + b) & máscara
signo_a = a & signo_mask
signo_b = b & signo_mask
signo_s = suma & signo_mask
overflow = (signo_a == signo_b) y (signo_s ≠ signo_a)
return suma, overflow
Ejercicio para el alumnado:
Solicitar que implementen un sumador/restador de enteros de 8 bits
en Python, probando casos como +100 + +50, +100 + (−30), −50 −
(−120), detectando overflow.
Extender a 16 o 32 bits, probando álveos de signos y mostrando
resultados decimales.
11.4 Codificación de cadenas en ASCII y UTF-8: representación y
almacenamiento en archivos
Objetivo: Comprender cómo se codifican cadenas de texto en archivos con
ASCII y UTF-8, y cómo leer/guardar archivos en cada formato.
1. Actividad manual – ASCII:
o Dar una cadena corta, por ejemplo, “Hola!”.
o Listar la tabla ASCII (7 o 8 bits) de cada carácter:
arduino
'H' → 0x48 (01001000₂)
'o' → 0x6F (01101111₂)
'l' → 0x6C (01101100₂)
'a' → 0x61 (01100001₂)
'!' → 0x21 (00100001₂)
o Mostrar cómo se escribirían secuencialmente esos bytes en un
archivo binario.
2. UTF-8 para caracteres no ASCII:
o Extender la cadena a “¡Hola, mundo!” (incluye ‘¡’ U+00A1 y ‘ñ’
U+00F1).
o Codificar cada carácter en UTF-8:
‘¡’ (U+00A1) → 0xC2 0xA1 (11000010 10100001₂).
Resto (‘H’, ‘o’, …) se codifican como un solo byte igual
que ASCII.
‘ñ’ (U+00F1) → 0xC3 0xB1 (11000011 10110001₂).
o Escribir la secuencia completa de bytes en un archivo y
visualizarlo en un editor hex.
3. Implementación en Python:
python
texto = "¡Hola, mundo!"
# Codificar en ASCII (dará error si hay caracteres fuera de 0–127)
try:
ascii_bytes = [Link]('ascii')
print("ASCII:", ascii_bytes)
except UnicodeEncodeError as e:
print("Error ASCII:", e)
# Codificar en UTF-8
utf8_bytes = [Link]('utf-8')
print("UTF-8:", utf8_bytes)
# Guardar en archivos
with open('salida_ascii.txt', 'wb') as f:
try:
[Link](ascii_bytes)
except NameError:
pass # No hay ASCII si dio error
with open('salida_utf8.txt', 'wb') as f:
[Link](utf8_bytes)
# Leer de archivo y decodificar
with open('salida_utf8.txt', 'rb') as f:
contenido = [Link]()
print("Leído de UTF-8:", [Link]('utf-8'))
4. Verificación con editores hex:
o Abrir los archivos .txt en un visor hexadecimal y confirmar la
correspondencia byte a byte con la codificación explicada.
11.5 Construcción de un pequeño “visualizador” de imágenes
BMP/PNG para ver el almacenamiento de píxeles
Objetivo: Que el alumnado entienda cómo se almacenan los píxeles en
formatos sin compresión (BMP/RAW) y sin pérdida (PNG), construyendo una
herramienta básica en Python que lea el archivo y muestre información
interna.
1. Formatos a usar:
o BMP (Bitmap): estructura muy sencilla, con cabecera y datos
de píxeles sin compresión (o con RLE opcional).
o PNG: más complejo (compresión sin pérdida Deflate, filtros
previos), pero la librería Python facilita su lectura.
2. Ejercicio paso a paso en Python (usando Pillow o lectura
manual de BMP):
a. Lectura de cabecera BMP:
python
import struct
def leer_bmp(ruta):
with open(ruta, 'rb') as f:
cabecera = [Link](14) # Cabecera BMP
info_header = [Link](40) # InfoHeader Windows BMP
# Desempaquetar ancho, alto, profundidad de color, desplazamiento,
etc.
_, _, offset = [Link]('<2sI I', cabecera) # 'BM', tamaño, offset
largura, altura, planos, bpp = [Link]('<iiHH', info_header[:12])
print(f"Ancho: {largura}, Alto: {altura}, Bits por píxel: {bpp}, Offset:
{offset}")
# Leer datos de píxeles
[Link](offset)
num_bytes_pixel = bpp // 8
fila_bytes = ((largura * num_bytes_pixel + 3) // 4) * 4 # Alineación a 4
bytes
datos = []
for y in range(abs(altura)):
fila = [Link](fila_bytes)
fila_pixeles = []
for x in range(largura):
inicio = x * num_bytes_pixel
if bpp == 24:
b, g, r = fila[inicio:inicio+3]
fila_pixeles.append((r, g, b))
elif bpp == 8:
(idx,) = fila[inicio:inicio+1]
fila_pixeles.append(idx) # índice a paleta (no manejada aquí)
# Extendible a 32 bpp
[Link](fila_pixeles)
return largura, altura, bpp, datos
# Ejemplo de uso:
ancho, alto, bpp, pixeles = leer_bmp('[Link]')
print(f"Primer píxel (esquina inferior izquierda): {pixeles[-1][0]}")
b. Mostrar algunos valores de píxeles
o Por ejemplo, imprimir los primeros 10 píxeles de la primera fila
y la última fila, para ver el orden de almacenamiento (BMP
almacena filas de abajo a arriba).
c. Visualizar en pantalla (opcional)
python
from PIL import Image
def mostrar_bmp(ruta):
img = [Link](ruta)
[Link]()
mostrar_bmp('[Link]')
o Explicar que Pillow ya descodifica la estructura interna; la
actividad principal es extraer y mostrar manualmente algunos
bytes.
3. PNG con Pillow:
python
from PIL import Image
def leer_png(ruta):
img = [Link](ruta)
ancho, alto = [Link]
modo = [Link] # 'RGB', 'RGBA', 'L', etc.
pixeles = [Link]()
print(f"Ancho: {ancho}, Alto: {alto}, Modo: {modo}")
# Mostrar algunos píxeles
for y in range(min(alto, 3)):
for x in range(min(ancho, 5)):
print(f"({x}, {y}): {pixeles[x, y]}")
leer_png('[Link]')
4. Reporte de actividad:
o El alumno documenta qué bytes corresponden a cada píxel
para BMP (orden BGR) y cómo PNG almacena internamente (sin
que vea la compresión).
o Comparar tamaños de un BMP sin compresión y el
correspondiente PNG comprimido sin pérdida.
11.6 Grabación de audio PCM y análisis de muestra y frecuencia
usando Audacity o similar
Objetivo: Familiarizarse con la captación de audio PCM y el análisis de sus
parámetros (frecuencia de muestreo, bits de cuantificación) empleando un
editor de audio.
1. Grabación de audio en PCM:
o Abrir Audacity (software libre).
o Configurar proyecto con:
Frecuencia de muestreo: 44 100 Hz.
Resolución de 16 bits (formato PCM).
o Grabar unos segundos usando el micrófono incorporado.
o Detener grabación y observar la forma de onda.
2. Análisis de parámetros:
o En la parte inferior izquierda, Audacity mostrará “Proyecto Rate
(Hz)” = 44100.
o Exportar el archivo como WAV (PCM sin compresión).
o Usar un visor hexadecimal o una herramienta como sox --i
[Link] para verificar:
Cabecera RIFF: los primeros bytes indican “RIFF” (52 49
46 46 en ASCII).
Formato “WAVE” y subchunk “fmt ”.
Frecuencia, canales (mono/estéreo), bits por muestra en
la cabecera.
3. Visualización de muestras y frecuencias:
o Seleccionar una porción pequeña y hacer zoom para ver el
muestreo:
Cada punto en la forma de onda corresponde a una
muestra (muestra cada 1/44100 s).
Ajustar vista de “Mostrar muestras” y “Mostrar tiempo
(s)” para comprobar intervalos de tiempo.
o Exportar a texto la gráfica de amplitudes si se desea análisis
numérico (Archivo → Exportar → Exportar datos de audio).
4. Generación de tonos para ver cuantificación:
o Generar un tono puro (Efectos → Generar → Tono), por ejemplo
440 Hz, 5 s, tono seno.
o Observar la forma de onda y cómo las muestras digitales
aproximan la forma analógica.
o Cambiar la profundidad de bits a 8 bits y ver cómo la ola se
“digitaliza” con escalones más anchos (mayor error de
cuantificación).
11.7 Simulación de detección de errores con bits de paridad y
códigos de Hamming en Logisim
Objetivo: Usar el simulador Logisim para diseñar circuitos que
añadan/parade radios, detecten y corrijan errores de un bit mediante
códigos de Hamming.
1. Bits de paridad:
o En Logisim, crear un circuito que reciba 7 bits de datos y
genere 1 bit de paridad (par/impar).
o Implementar la lógica XOR de todos los bits:
Insertar 6 puertas XOR en cascada para el conjunto de 7
bits.
Conectar la salida al pin de “paridad” adicional.
o Verificar: inyectar un bit 1 erróneo y observar cómo la salida de
paridad cambia, indicando un error.
2. Código de Hamming (7,4):
o Diseñar el clásico Hamming(7,4) que toma 4 bits de datos (d₁,
d₂, d₃, d₄) y genera 3 bits de paridad (p₁, p₂, p₃).
o Mapa de posiciones de 1 a 7:
yaml
Pos 1: p₁
Pos 2: p₂
Pos 3: d₁
Pos 4: p₃
Pos 5: d₂
Pos 6: d₃
Pos 7: d₄
o Lógica para cada paridad:
p₁ = d₁ ⊕ d₂ ⊕ d₄
p₂ = d₁ ⊕ d₃ ⊕ d₄
p₃ = d₂ ⊕ d₃ ⊕ d₄
o En Logisim:
Colocar 4 entradas de datos.
Conectar puertas XOR según las fórmulas anteriores
para obtener p₁, p₂ y p₃.
Emular transmisión: unir los 7 bits a un bus.
Para simular un error, insertar una puerta XOR adicional
controlada por un interruptor que flipee el contenido de
un bit.
Diseñar lógica combinacional que recalcule los bits de
paridad de la trama recibida y genere el síndrome de 3
bits (s₂ s₁ s₀).
El valor binario del síndrome (1..7) indica la posición del
bit erróneo; conectar a un módulo que aplique XOR en
esa posición para invertirlo y corregirlo.
3. Verificación:
o Probar todos los casos en los que se invierta un único bit
(posición 1..7), observando cómo el circuito detecta la posición
correcta y la corrige.
o Validar que si no hay error, el síndrome es 000₂ y no se corrige
nada.
11.8 Análisis comparativo de compresión JPEG vs PNG para una
misma imagen (calidad vs tamaño)
Objetivo: Evaluar cuantitativamente las diferencias entre compresión sin
pérdida (PNG) y con pérdida (JPEG) en una misma imagen, analizando
calidad visual y tamaño resultante.
1. Selección de imagen de prueba:
o Elegir una fotografía o gráfico de resolución moderada (p. ej.,
800×600, 24 bpp).
o Guardar la versión original en BMP para obtener el tamaño sin
compresión.
2. Comprimir a PNG (sin pérdida):
o Usar un editor (GIMP, [Link], Photoshop) para exportar a
PNG.
o Anotar tamaño resultante en disco (bytes).
o Observación: la compresión PNG puede variar según el
contenido (imágenes con grandes áreas de color uniforme se
comprimen mejor que fotografías complejas).
3. Comprimir a JPEG (pérdida):
o Exportar la misma imagen a JPEG con distintas calidades: 100
%, 80 %, 60 %, 40 %.
o Registrarse tamaño para cada nivel de calidad.
o Ver visualmente en cada versión las diferencias (artefactos,
pérdida de nitidez).
4. Medición de calidad (opcional):
o Usar una métrica como PSNR (Peak Signal-to-Noise Ratio) para
cuantificar la diferencia entre el original y cada JPEG
comprimido.
o En Python, se puede usar OpenCV o PIL + NumPy para calcular
MSE (mean squared error) y PSNR:
python
from PIL import Image
import numpy as np
import math
def calcular_psnr(im1, im2):
arr1 = [Link](im1).astype(np.float64)
arr2 = [Link](im2).astype(np.float64)
mse = [Link]((arr1 - arr2) ** 2)
if mse == 0:
return float('inf')
PIXEL_MAX = 255.0
return 20 * math.log10(PIXEL_MAX / [Link](mse))
original = [Link]('imagen_original.bmp')
jpeg80 = [Link]('imagen_80.jpg')
print("PSNR calidad 80:", calcular_psnr(original, jpeg80))
5. Presentación de resultados:
o Crear una tabla comparativa con columnas: Formato, Calidad
(si aplica), Tamaño (Bytes), PSNR (dB), Observaciones
(artefactos visibles, compresión de áreas lisas, etc.).
o Discutir en clase cuándo conviene PNG (gráficos, logos, texto
en imagen) y cuándo JPEG (fotografías, streaming).
12. Conclusión
12.1 Importancia de la representación interna en todas las capas
del sistema informático
La representación interna de los datos es la base sobre la que
funciona cualquier componente de hardware y software:
o Desde cómo la CPU interpreta números y realiza operaciones.
o Hasta cómo un navegador web decodifica caracteres y
formatos multimedia.
Tener un dominio preciso sobre la codificación de enteros, reales,
texto, imágenes o audio es esencial para:
o Diseñar sistemas eficientes (elegir el tipo de dato y tamaño
adecuado en memoria).
o Garantizar compatibilidad entre componentes heterogéneos
(por ejemplo, endianess, formatos de archivo).
o Optimizar recursos (espacio en disco, ancho de banda de
red, tiempo de procesado).
12.2 Necesidad de dominar estos conceptos para optimizar
rendimiento, compatibilidad y seguridad
Rendimiento:
o Una operación aritmética en complemento a 2 se realiza
directamente en hardware, pero si el programador no entiende
overflow puede generar bugs complejos.
o El acceso a datos alineados a la palabra o al doble palabra
acelera la lectura/escritura en memoria y reduce fallos de
caché.
Compatibilidad:
o Convertir “big endian” a “little endian” correctamente es
fundamental cuando se intercambian datos en red o entre
arquitecturas distintas.
o Usar UTF-8 correctamente garantiza que aplicaciones y
sistemas operativos manejen texto multilingüe sin errores de
codificación.
Seguridad:
o Los algoritmos de cifrado simétrico y hash operan a nivel de
bits y bloques; errores en la alineación o en la manipulación de
bytes pueden dejar vulnerabilidades.
o Detectar y corregir errores en transmisión (CRC, Hamming)
evita corrupciones de datos o explotaciones maliciosas.
12.3 Tendencias futuras: compresión avanzada, representaciones
en sistemas cuánticos, tecnologías emergentes
Compresión avanzada:
o Códecs de próxima generación (AV1 para vídeo, Opus para
audio) mejoran la eficiencia con técnicas de aprendizaje
automático y predicción avanzada.
o Formatos de compresión adaptativa en tiempo real para
streaming 4K/8K y realidad virtual.
Sistemas cuánticos y representación de datos cuánticos:
o En computación cuántica, los “qubits” representan información
en superposición de 0 y 1.
o El concepto de codificar datos en qubits exige nuevos modelos
de representación (registros cuánticos, puertas cuánticas) y
técnicas de corrección de errores cuánticos.
Internet de las Cosas (IoT) y dispositivos embebidos:
o La representación de datos en microcontroladores de bajo
consumo (8 o 16 bits) y la transmisión de trillones de sensores
en redes heterogéneas obligan a formatos ultracompactos.
o Protocolos ligeros (MQTT-SN, CoAP) usan codificaciones binarias
concisas (CBOR, MessagePack) que reducen el overhead de
JSON/XML.
Lógica reconfigurable y FPGAs:
o La representación de datos en hardware programable permite
diseñar módulos de compresión o cifrado “a medida” a nivel de
bit, optimizando aún más el rendimiento y la eficiencia
energética.
En definitiva, comprender cómo se representan, almacenan y manipulan los
datos en cada nivel —desde el byte simple hasta complejos flujos
multimedia— es clave para cualquier profesional de sistemas y aplicaciones
informáticas. Estos conocimientos constituyen la piedra angular para
diseñar, optimizar y asegurar sistemas modernos en constante evolución.
Crear un índice del tema “Representación interna de los datos” para
preparar las oposiciones de secundaria de formación profesional de la
especialidad de sistemas y aplicaciones informáticas, incluyendo relación
con otros módulos y actividades para que realicen los alumnos
Desarrolla con detalle los siguientes apartados del tema “Representación
interna de los datos" para la oposición de sistemas y aplicaciones
informáticas de formación profesional.
11. Actividades prácticas para el alumnado
11.1 Conversión manual y programada entre sistemas de numeración
11.2 Diseño y simplificación de expresiones booleanas con mapas de
Karnaugh
11.3 Implementación de operaciones binarias (suma/resta en complemento
a 2) en pseudocódigo o Python
11.4 Codificación de cadenas en ASCII y UTF-8: representación y
almacenamiento en archivos
11.5 Construcción de un pequeño “visualizador” de imágenes BMP/PNG para
ver el almacenamiento de píxeles
11.6 Grabación de audio PCM y análisis de muestra y frecuencia usando
Audacity o similar
11.7 Simulación de detección de errores con bits de paridad y códigos de
Hamming en Logisim
11.8 Análisis comparativo de compresión JPEG vs PNG para una misma
imagen (calidad vs tamaño)
12. Conclusión
12.1 Importancia de la representación interna en todas las capas del
sistema informático
12.2 Necesidad de dominar estos conceptos para optimizar rendimiento,
compatibilidad y seguridad
12.3 Tendencias futuras: compresión avanzada, representaciones en
sistemas cuánticos, tecnologías emergentes