descargar java math floating-point pow

descargar - java offline



Math.pow produce resultados diferentes según la versión de Java (4)

Estoy ejecutando el siguiente código en una versión JDK 1.7.0_60:

System.out.println(Math.pow(1.5476348320352065, (0.3333333333333333)));

El resultado es: 1.1567055833133086

Estoy ejecutando exactamente el mismo código en una JDK versión 1.7.0.

El resultado es: 1.1567055833133089

Entiendo que el doble no es infinitamente preciso, pero ¿hubo algún cambio en la especificación Java que causa la diferencia?

PD: Debido a que usamos un sistema heredado, Big Decimal no es una opción.

Editar: Pude rastrear el momento del cambio: se introdujo en la versión JDK 1.7.0_40 (en comparación con la versión 1.7.0_25).


pero ¿hubo algún cambio en las especificaciones de java que causa la diferencia?

No. * Según los Javadocs para Math.pow , se Math.pow una diferencia de hasta un ULP (Unidad en el último lugar). Si echamos un vistazo a sus dos valores:

System.out.printf("%016x/n", Double.doubleToLongBits(1.1567055833133086)); System.out.printf("%016x/n", Double.doubleToLongBits(1.1567055833133089));

obtenemos:

3ff281ddb6b6e675 3ff281ddb6b6e676

que de hecho difieren en un ULP.

Lo que está viendo probablemente se deba a pequeñas diferencias en la secuencia de instrucciones de coma flotante utilizadas por el JDK / JVM para implementar estas operaciones.

* Al menos, ¡no tan lejos como sé!

No hubo cambios en la especificación, pero se han producido algunos cambios en el optimizador de zona activa que podrían (!) Estar relacionados con esto.

Desenterré estas partes del código:

(Estas no son exactamente las versiones donde se han introducido estos cambios, solo los elegí debido a la información de la versión que proporcionó).

Los cambios (y lo que el código está haciendo) van más allá de lo que puedo analizar en un tiempo razonable, pero tal vez alguien encuentre esta referencia interesante o útil.


Para producir resultados consistentes entre todas las versiones de Java, la solución era usar StrictMath.pow() lugar de Math.pow() .

Para obtener información general sobre lo que podría causar la diferencia, consulte esta respuesta .