🧮 Computational Mathematics

Inicio · Parte 01 — Aritmética computacional y representación numérica

031 — ULP y machine epsilon

basico-computacional clase 11 de 20 4 horas demostración ulp_epsilon

El epsilon de máquina mide la precisión relativa; el ULP mide la distancia absoluta entre floats vecinos.

Fórmulas

ε = 2⁻⁵² ≈ 2.22e−16  (float64)
ulp(x) ≈ ε · 2^⌊log₂|x|⌋

Desarrollo

El epsilon de máquina se define como el menor ε tal que 1 + ε ≠ 1 en la aritmética del formato. En float64 vale exactamente 2⁻⁵², porque la mantisa tiene 52 bits almacenados: sumar algo menor que el último bit de la mantisa no cambia el número. El laboratorio comprueba justamente eso: 1.0 + ε difiere de 1.0, pero 1.0 + ε/2 no.

El ULP —unit in the last place— es el concepto relacionado pero distinto: la distancia entre un float concreto y su vecino inmediato. No es constante: cerca de 1 vale unos 2.2·10⁻¹⁶, cerca de 10⁶ vale unos 1.2·10⁻¹⁰, y cerca de 10⁻⁶ vale unos 2.1·10⁻²². Los floats no están repartidos uniformemente en la recta: se concentran cerca del cero y se espacian al alejarse.

Esta no uniformidad explica un fenómeno cotidiano: sumar un número muy pequeño a uno muy grande no cambia nada. 1e16 + 1.0 devuelve 1e16 porque 1.0 es menor que el ULP en esa escala. No es un redondeo agresivo: es que el resultado exacto no tiene representación y el más cercano es el propio 1e16.

Medir un error en ULP en lugar de en unidades absolutas es la forma correcta de evaluar la calidad de una función numérica. Una implementación de sin «correctamente redondeada» tiene un error menor a 0.5 ULP; una aceptable, menor a 1 ULP. Esa es la unidad en la que las bibliotecas matemáticas declaran su precisión.

Ejemplo trabajado

Epsilon, ULP y el límite de la suma.

ε = sys.float_info.epsilon = 2.220446049250313e−16 = 2⁻⁵²

1.0 + ε      ≠ 1.0        ✓ (por definición de ε)
1.0 + ε/2    == 1.0       ✓ (por debajo del último bit)

ULP según la magnitud:
  ulp(1.0)   = 2.22e−16
  ulp(1e6)   = 1.16e−10       500 000 veces mayor
  ulp(1e−6)  = 2.12e−22

Siguiente float tras 1.0: 1.0000000000000002

Los floats no son un retículo uniforme: son casi logarítmicos.

Qué calcula el laboratorio

Machine epsilon y la distancia al float siguiente.

python classes/part-01-aritmetica-computacional-y-representacion-numerica/031-ulp-y-machine-epsilon/lab.py
compmath run 031

Salidas del laboratorio (8)

Muestra de la ejecución real

{
  "sys.float_info.epsilon": 2.220446049250313e-16,
  "2**-52": 2.220446049250313e-16,
  "1.0 + eps != 1.0": true,
  "1.0 + eps/2 == 1.0": true,
  "ulp_en_1.0": 2.220446049250313e-16,
  "ulp_en_1e6": 1.1641532182693481e-10
}

Errores comunes

Dónde se usa

Elegir tolerancias, evaluar la calidad de una biblioteca matemática y entender por qué un acumulador pierde términos pequeños. Es el prerrequisito de las clases 032 y 034.

Idea rectora de la parte

Un float es un racional binario de precisión finita, no un número real.

Error a evitar

Suponer que la suma de floats es asociativa.

Conexión con IA

float32, bfloat16 y la cuantización a int8 son decisiones de representación. Los NaN en un entrenamiento casi siempre nacen aquí, no en la arquitectura.

Bibliografía de la clase

Archivos de la clase