Manejo de Errores de Precisión en JavaScript y PHP con EPSILON

Suma de Presición Arbitraria

Los números en coma flotante presentan desafíos en muchos lenguajes de programación debido a errores de precisión. En este artículo, te mostraremos cómo manejar estos errores en JavaScript y PHP utilizando el concepto de EPSILON, un valor de tolerancia que nos ayuda a obtener resultados más precisos en cálculos y comparaciones de números decimales.

¿Por Qué Ocurren los Errores de Precisión en Números Decimales?

La mayoría de los lenguajes de programación, incluidos JavaScript y PHP, almacenan números decimales en un formato binario llamado IEEE 754. Este formato tiene una precisión limitada y no puede representar con exactitud algunos números decimales comunes. Por ejemplo, al sumar 0.1 y 0.2, la respuesta exacta debería ser 0.3, pero el valor almacenado en binario puede terminar siendo algo como 0.30000000000000004.

Veamos este problema en acción en ambos lenguajes:

Ejemplo en JavaScript

Ejemplo en PHP

En ambos casos, la comparación devuelve false porque 0.1 + 0.2 no es exactamente 0.3. Esta inexactitud puede llevar a errores en comparaciones y cálculos, especialmente en aplicaciones que requieren precisión, como las financieras.

Introducción a Number.EPSILON en JavaScript

JavaScript incorpora Number.EPSILON, una constante que representa el menor número positivo que, sumado a 1, da un resultado diferente de 1. Su valor es aproximadamente 2.22e-16. Esto permite manejar de forma efectiva los errores de precisión mediante la definición de un margen de tolerancia.

Comparaciones Precisas con Number.EPSILON en JavaScript

Al realizar comparaciones entre números en JavaScript, puedes usar Number.EPSILON para establecer una «zona de tolerancia» y así considerar iguales dos números que son muy cercanos entre sí:

Aquí, la función areFloatsEqual compara la diferencia entre los números a y b con Number.EPSILON. Si la diferencia es menor que EPSILON, consideramos los números como «prácticamente iguales».

EPSILON en PHP

PHP no tiene un EPSILON predefinido como JavaScript, pero podemos definir uno manualmente para lograr el mismo efecto. En PHP, puedes establecer un EPSILON de manera similar:

Con esta constante EPSILON, podemos crear una función similar para comparar números de coma flotante en PHP:

Esta función en PHP tiene el mismo propósito que su equivalente en JavaScript: permitir que dos números que están muy cerca entre sí se consideren iguales, evitando errores de precisión en comparaciones directas.

Usando EPSILON para Redondeo Preciso

El problema de precisión también afecta el redondeo de números. Por ejemplo, al redondear 1.005 a dos decimales, podrías esperar 1.01, pero podrías obtener 1.00 debido a estos errores de precisión. Para corregir esto, se puede sumar EPSILON antes de redondear.

Redondeo Preciso en JavaScript

Redondeo Preciso en PHP

En ambos ejemplos, sumamos EPSILON al valor antes de redondearlo para evitar problemas de precisión. Esta técnica asegura que el redondeo funcione correctamente en situaciones donde el valor está muy cerca del límite de redondeo debido a la representación binaria.

Cuándo Usar EPSILON y Cuándo No

El uso de EPSILON es especialmente útil cuando:

  • Comparas números decimales que han sido generados por cálculos matemáticos y que pueden tener pequeños errores de precisión.
  • Realizas redondeos precisos en aplicaciones que dependen de cálculos exactos.

Para aplicaciones en las que los cálculos decimales deben ser altamente precisos (como en sistemas financieros), considera utilizar bibliotecas de aritmética de precisión arbitraria en ambos lenguajes:

  • JavaScript: Usa bibliotecas como Decimal.js que proporcionan precisión arbitraria para números decimales.
  • PHP: Usa la extensión BCMath, que incluye funciones para operaciones matemáticas con números de precisión arbitraria.

Conclusión

Los errores de precisión en los números en coma flotante son un desafío común en JavaScript, PHP y muchos otros lenguajes. Usar EPSILON es una manera eficaz de evitar problemas de precisión al comparar y redondear números en coma flotante. Aunque JavaScript cuenta con Number.EPSILON, en PHP podemos crear nuestra propia versión y aplicar técnicas similares para mejorar la precisión de nuestras operaciones.

Ahora que conoces estas técnicas, ¡intenta aplicarlas en tus proyectos de desarrollo web para ver cómo mejoran la precisión de tus cálculos y comparaciones!