Duplicar posibles:
Retain precision with Doubles in javade Java de doble precisión con la constante multiplicación/división
¿Conoce la diferencia entre estas dos operaciones en Java.
final double m1 = 11d/1e9; // gives 1.1e-8
final double m2 = 11d * 1e-9; // gives 1.1000000000000001e-8
Veo en el bytecode generado que el resultado precompilado de m2 ya no es lo que esperaba.
En la salida de javap -verbose -c
puedo ver el siguiente valor:
const #3 = double 1.1E-8d;
[...]
const #6 = double 1.1000000000000001E-8d;
Cuando uso M1 o M2 en otras expresiones, que no tienen el mismo resultado.
Cuando intento lo mismo en C, m1 y m2 es estrictamente 1.1E-8
Creo que mi problema es en la forma de Java maneja doble cómputo de precisión pero no puedo explicarme lo que extraño.
Ok esa es la explicación para Java, pero ahora ¿por qué cuando ejecuto el mismo código en C tengo toda la precisión que necesitaba? – Joker
El compilador de C optimizará el código * mucho * más que 'javac'. Esto puede significar que podría traducir '/ 1e-9' a' * 1e9' porque a) es más rápido yb) más preciso.El compilador de Java realiza muy pocas optimizaciones, esto se deja al JIT, lo que también significa que el código optimizado y no optimizado debe hacer lo mismo; de lo contrario, vería un cambio en el comportamiento mientras se ejecuta el programa. La conversión de un 'doble' a una cadena es diferente en C y Java también, pero es menos probable que sea la causa de la diferencia. En ambos casos, usan la misma FPU. –
También el compilador de C podría hacer uso de los cómputos/cómputos de punto flotante de 80 bits que tiene su computadora. Esto depende de la plataforma y solo está disponible en procesadores x86/x64. Java se comportará igual en todas las plataformas, por lo que solo usará coma flotante de 64 bits, incluso si el punto flotante de 80 bits está disponible. –