Подтвердить что ты не робот

Math.pow дает разные результаты в зависимости от версии java

Я запускаю следующий код на JDK версии 1.7.0_60:

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

Результат: 1.1567055833133086

Я запускаю точно такой же код на JDK версии 1.7.0.

Результат: 1.1567055833133089

Я понимаю, что double не бесконечно точен, но было ли изменение в спецификации java, которое вызывает разницу?

PS: Поскольку мы используем устаревшую систему, Big Decimal не является вариантом.

Изменить: мне удалось отследить время изменения: оно было введено в версии JDK версии 1.7.0_40 (по сравнению с версией 1.7.0_25).

4b9b3361

Ответ 1

Чтобы обеспечить согласованные результаты между всеми версиями Java, решение заключалось в использовании StrictMath.pow() вместо Math.pow().

Для получения справочной информации о том, что может вызвать разницу, обратитесь к этому ответу.

Ответ 2

но было ли изменение спецификации java, которое вызывает разницу?

Нет * В соответствии с Javadocs для Math.pow разница в размере до одного ULP (единица на последнем месте). Если мы посмотрим на ваши два значения:

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

получаем:

3ff281ddb6b6e675
3ff281ddb6b6e676

которые действительно отличаются одним ULP.

То, что вы видите, вероятно, связано с небольшими различиями в последовательности инструкций с плавающей запятой, используемых JDK/JVM для реализации этих операций.


* По крайней мере, насколько я знаю!

Ответ 3

В спецификации не было изменений, но в оптимизаторе точек доступа были некоторые изменения, которые могут (!) быть связаны с этим.

Я выкопал эти части кода:

(это не совсем версии, в которых эти изменения были введены, я просто выбрал их из-за информации о версии, которую вы предоставили).

Изменения (и то, что делает код вообще) намного превосходят то, что я могу проанализировать в разумные сроки, но, возможно, кто-то найдет эту ссылку интересной или полезной.