🧮 Computational Mathematics

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

037 — Precisión arbitraria y Decimal

basico-computacional clase 17 de 20 4 horas demostración arbitrary_precision

Decimal ofrece precisión decimal declarada y exacta a cambio de velocidad.

Fórmulas

Decimal('0.1') · 3 == Decimal('0.3')  → True
0.1 * 3 == 0.3  → False

Desarrollo

El módulo decimal implementa aritmética de punto flotante en base 10 con precisión configurable. Su ventaja no es tener más dígitos: es que las fracciones decimales que escribimos —0.1, 0.05, 19.99— son exactamente representables, porque la base coincide con la de nuestra notación.

Eso resuelve de raíz el problema del dinero. Decimal('0.1') 3 da exactamente Decimal('0.3'), mientras que 0.1 3 en float da 0.30000000000000004. Además, Decimal permite declarar la precisión (getcontext().prec) y el modo de redondeo, de modo que el comportamiento queda documentado en el código en lugar de depender del hardware.

El coste es real: Decimal es entre 50 y 100 veces más lento que float porque no se apoya en la FPU. Para un cálculo científico con millones de operaciones es inaceptable; para calcular el total de una factura es irrelevante.

Un detalle que atrapa a muchos: Decimal(0.1) —con un float como argumento— hereda el error del float y da 0.1000000000000000055511151231257827. Hay que construirlo desde cadena: Decimal('0.1'). La firma acepta ambos precisamente para poder inspeccionar qué guarda realmente un float, que es lo que hace el laboratorio de la clase 029.

Ejemplo trabajado

Exactitud decimal frente a binaria.

getcontext().prec = 50

Decimal(1)/Decimal(3) =
  0.33333333333333333333333333333333333333333333333333   (50 dígitos)
1/3 (float) = 0.3333333333333333                          (16 dígitos)

Decimal('0.1') * 3 == Decimal('0.3')   →  True   ✓
0.1 * 3 == 0.3                          →  False  ✗

Trampa:
  Decimal(0.1)   → 0.1000000000000000055511151231257827...
  Decimal('0.1') → 0.1                                    ✓

Qué calcula el laboratorio

Decimal con precisión declarada frente a float.

python classes/part-01-aritmetica-computacional-y-representacion-numerica/037-precision-arbitraria-y-decimal/lab.py
compmath run 037

Salidas del laboratorio (6)

Muestra de la ejecución real

{
  "precision_configurada": 50,
  "1/3_decimal": "0.33333333333333333333333333333333333333333333333333",
  "1/3_float": 0.3333333333333333,
  "suma_0.1x3_decimal": "0.3",
  "es_exactamente_0.3": true,
  "coste": "exactitud decimal a cambio de velocidad"
}

Errores comunes

Dónde se usa

Contabilidad, facturación, impuestos, cálculo de intereses y cualquier dominio con reglas de redondeo normativas. Es el estándar en sistemas financieros.

Idea rectora de la parte

El error relativo, no el absoluto, es la magnitud que se propaga.

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