¿Qué pasa si restas?
9999999999999999.0 – 9999999999999998.0 = ?
El resultado depende un poco del lenguaje. En la mayoría de los casos el resultado será 2.
Esta es la pregunta que se hizo Geo Carncross y hace el experimento con varios lenguajes de programación.
Seguramente lo habrás aprendido en la escuela, pero es un aspecto de la programación que suele olvidarse con frecuencia.
La razón tiene que ver más con la forma en la que se almacenan valores decimales en la memoria que con la operación misma. En el caso de Java por ejemplo, un valor de punto flotante de doble precisión como el tipo double es un valor de 64 bits, donde:
1 bit denota el signo (positivo o negativo).
11 bits para el exponente.
52 bits para los dígitos significativos (la parte fraccionaria como un binario) .
Estas partes se combinan para producir un valor decimal double.
De este modo cuando realizas la resta, realmente estás haciendo la operación sobre valores diferentes de los que especificaste durante la edición del código.
package com.decodigo; /** * * @author decodigo.com */ public class Prueba { public static void main(String args[]){ double a = 9999999999999999.0; double b = 9999999999999998.0; double resultado = a - b; System.out.println("a: " + a); System.out.println("b: " + b); System.out.println("resultado: " + resultado); } }
El resultado en consola será:
a: 1.0E16
b: 9.999999999999998E15
resultado: 2.0
Un número decimal no se representa exactamente en la memoria, aunque en apariencia tengan incluso el mismo número de dígitos mientras estás escribiendo el código. Cuando el compilador convierte los valores de a y b a un número de coma flotante, sus valores se aproximan para ser representados internamente en formato binario y se complementan con el exponente si se excede la capacidad de los dígitos significativos.
Adicionalmente, cuantas más operaciones se realicen con un número de punto flotante, mayor será el número de errores de redondeo.