Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Math.pow() in Java 8 and Java 13 returns different result

Tags:

java

math

jvm

This following code returns different results on Java 8 and Java 11.

class Playground {
    public static void main(String[ ] args) {
        long x = 29218;
        long q = 4761432;
        double ret = Math.pow(1.0 + (double) x / q, 0.0005);
        System.out.println("val = " + String.format("%.24f", ret));
    }
}

Java 8:

val = 1.000003058823805400000000

Java 11: (The same result as Python, Rust)

val = 1.000003058823805100000000

The questions are these:

  • Any documentation to describe this kind of behavior?
  • How to implement Java 8's Math.pow() in Python?
  • How to ensure strict consistency with older programs using the Java 8 library?
like image 431
Andelf Avatar asked Mar 03 '26 19:03

Andelf


1 Answers

If we just use Double.toString() to print the answers then the two different results would be

1.0000030588238054
1.0000030588238051

The extra digits at the end are just a factor of the String.format(). We see the numbers only differ by the last significant decimal digit. Converting the two numbers to hexadecimal give

1.000033518c576
1.000033518c575

so the binary representations only differ by one unit in the last place (ulp).

Reading the spec for Math.pow we find

"The computed result must be within 1 ulp of the exact result."

The true value is close to 1.000003058823805246468 (WolframAlpha) somewhere between the two answers, so both are within the spec.

All which has happened is that the library has had a slight change in algorithm, maybe to make it faster.

like image 154
Salix alba Avatar answered Mar 06 '26 09:03

Salix alba



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!