[Spanish] El misterio del error de precisión de los números de punto flotante

Finalmente he podido entender el misterio del error de precisión de los números de punto flotante que afecta a todos los lenguajes de programación. Para explicarlo, voy a emular el trabajo que realiza el computador para almacenar y leer el número decimal 0.1

Como los computadores almacenan todos los números y caracteres en binario, el primer paso es transformar el número decimal 0.1 a su representación binaria. Para ello se sigue un algoritmo sencillo:

1) Se toma el número a transformar y se multiplica por 2:

0.1 * 2 = 0.2

2) Se separa la parte entera de la decimal del valor resultante

La parte entera de 0.2 es 0
La parte decimal de 0.2 es 0.2

3) La parte entera se toma como el primer dígito significativo del número binario

0.0______

3) Se repiten los pasos 1 y 2 usando la parte decimal obtenida del paso anterior.

Este proceso se repite hasta que el resultado de sea cero o se obtenga una secuencia periódica.

Si ejecutamos este proceso completo para el número 0.1 obtenemos lo siguiente:

0.1 * 2 = 0.2 -> 0
0.2 * 2 = 0.4 -> 0
0.4 * 2 = 0.8 -> 0
0.8 * 2 = 1.6 -> 1
0.6 * 2 = 1.2 -> 1
0.2 * 2 = 0.4 -> 0 (vuelve a reiniciarse la secuencia)

Con esto obtenemos que la representación binaria de 0.1 es:

0.00011... periódico

Como las computadoras tienen una cantidad finita de bits para almacenar cualquier número, los números periódicos se almacenarán truncados. Si asumimos que nuestra computadora solo almacena el valor 0.00011 y no 0.000110011001100110011... (hasta el infinito), la conversión de binario a decimal de este número sería:

0.00011 = 1/16 + 1/32 = 0.09375

Y con esto hemos comprobado cómo surge un problema de precisión pues 0.1 no es igual a 0.09375, es solo un valor aproximado.

7 thoughts on “[Spanish] El misterio del error de precisión de los números de punto flotante”

  1. De acuerdo. Así es. Y en todo caso si el computador fuera decimal, la memoria de longitud fija finita hace perder precisión. Ejemplo: la expresión de la raiz de 2 es una serie infinita o tiene infinitos numeros en su parte decimal imposibles de registrar en un computador.

  2. Por eso existen los métodos numéricos que tratan de minizar el efecto del control por redondeo y en muchos casos son métodos que en lugar de calcular directamente van produciendo aproximaciones a la respuesta cada vez mejores a medida que aumentan las iteraciones.

    1. Yo llegué a descubrir este error de precisión trabajando con Javascript, en alguna parte del código tenía una comparación simple del tipo if(a==b) que fallaba inexplicablemente

      1. Para evitar la posibilidad de error en comparaciones numéricas de igual, siempre se encontrará o es necesario algún truco. Ejemplo: En lugar de a=0, se compara a< 10^-7 o el numero conveniente que no supere la precisión del computador. Pero podría funcionar mal si por error o cálculo a no es positivo, en cuyo caso tendría que tener algo como 0<ab, en lugar de a=b, diría a-b<10^-7. Esos casos posibles requieren ingenio adicional. Cada caso puede ser diferente. Problemas podrían evitarse utilizando la función valor absoluto. En lugar de a=b estudiar abs(a-b)< 10^-7 por ejemplo

  3. Así es. por eso los algoritmos numéricos se diseñan para controlar y corregir el error por redondeo, mas es inevitable en general. Se habla de estabilidad cuando el algoritmo controla al máximo el error por redondeo y condición del problema que significa que un problema mal condicionado podría reventar aun ante un “algoritmo” estable.

Leave a Reply to asesordocentevenezuelaCancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.