Aritmética computacional: Endianness y los secretos de IEEE 754
Para la mayoría de los programadores, un número es solo un float o un int. Pero bajo la superficie, la forma en que una computadora almacena y manipula estos valores es un mundo complejo de elecciones específicas de la arquitectura y brillantes compromisos matemáticos.
En esta guía, exploraremos la representación de datos de bajo nivel, desde el orden de los bytes en la memoria hasta las sofisticadas matemáticas del estándar IEEE 754, incluidos los números subnormales que a menudo se pasan por alto.
1. El orden de las cosas: Endianness
Imagina que tienes un entero de 32 bits, 0x12345678. Consta de cuatro bytes: 0x12, 0x34, 0x56 y 0x78. ¿Cómo deberían almacenarse estos bytes en la memoria de tu computadora?
Big-Endian (El orden intuitivo)
In un sistema Big-Endian, el "extremo grande" (el byte más significativo) se almacena en la dirección de memoria más baja.
Addr 0: 0x12Addr 1: 0x34Addr 2: 0x56Addr 3: 0x78
Little-Endian (El estándar X86)
En un sistema Little-Endian (utilizado por casi todos los PC y smartphones modernos), el "extremo pequeño" se almacena primero.
Addr 0: 0x78Addr 1: 0x56Addr 2: 0x34Addr 3: 0x12
¿Por qué es importante? Orden de bytes de red
Al enviar datos a través de una red, diferentes computadoras pueden tener diferentes endianness. Para solucionar esto, los protocolos de Internet definen el Orden de bytes de red como Big-Endian. Cada vez que escribes código de red de bajo nivel, debes convertir tu "Orden de bytes del host" local al "Orden de bytes de red" antes de enviar, y viceversa al recibir.
2. Las matemáticas del punto flotante: IEEE 754
El estándar IEEE 754 es el lenguaje universal de la aritmética de punto flotante. Un flotante de 64 bits (un double) se divide en tres partes:
- Bit de signo (1 bit): 0 para positivo, 1 para negativo.
- Exponente (11 bits): Determina la escala del número.
- Fracción/Significante (52 bits): Determina la precisión.
Sesgo del exponente (Bias)
El exponente no se almacena como un entero simple. En su lugar, utiliza un Sesgo (1023 para doubles). Esto permite que el campo de 11 bits represente potencias de 2 tanto positivas como negativas sin necesidad de un bit de signo separado para el exponente mismo.
Significante vs. Mantisa
En el IEEE 754 moderno, usamos el término Significante. Consta de un "bit principal implícito" (generalmente 1) más la Mantisa (los bits realmente almacenados). Al asumir que el primer bit es 1, ahorramos un bit de espacio, ganando precisión extra.
3. Casos extremos: Números subnormales (desnormalizados)
En el punto flotante estándar, siempre se asume que el bit principal es 1. Pero, ¿qué sucede a medida que nos acercamos más y más a cero?
El "vacío" en el cero
Sin números subnormales, habría un gran "vacío" entre el número positivo más pequeño representable y el cero. Esto se llama "Underflow" (subdesbordamiento).
Números subnormales al rescate
Cuando el campo del exponente es todo ceros, el estándar IEEE 754 cambia al Modo subnormal.
- El bit principal implícito se convierte en 0 en lugar de 1.
- Esto permite que el número sufra un "subdesbordamiento gradual", proporcionando valores más pequeños de lo que sería posible de otra manera.
- El coste de rendimiento: En muchas CPU, la aritmética subnormal se maneja mediante microcódigo en lugar de la FPU principal del hardware, lo que la hace significativamente más lenta. Algunos softwares críticos para el rendimiento (como el procesamiento de audio o los juegos) activarán "Flush to Zero" (FTZ) para evitar este impacto en el rendimiento.
4. Valores especiales
- Infinito (Inf): El exponente son todo 1s, la mantisa son todo 0s.
- Not a Number (NaN): El exponente son todo 1s, la mantisa es distinta de cero.
- Cero con signo (-0.0): El IEEE 754 distingue entre +0 y -0, lo que puede provocar errores sutiles en las comprobaciones condicionales.
Conclusión
Comprender la aritmética computacional es como mirar bajo el capó de un motor de alto rendimiento. Desde el intercambio de bytes requerido por el endianness hasta la delicada lógica de "underflow" de los números subnormales, estos detalles de bajo nivel son los que permiten que nuestro software sea preciso y eficiente.
Ya sea que estés depurando un protocolo de red o optimizando un motor de física, ten en cuenta los secretos del IEEE 754 y las reglas del endianness: son la base invisible de cada cálculo que realizas.