Math.log(17197) produces inconsistent results between javac, jit, Math and StrictMath on various architectures.
xerxes at zafena.se
Tue May 25 01:37:51 PDT 2010
On 2010-05-24 20:12, Tom Rodriguez wrote:
> On May 24, 2010, at 5:55 AM, Xerxes Rånby wrote:
>> When running this testcase using various jvms / architectures i get varying results of the calculated log_result2 and log_result which
>> ARCH+JVM combination log_result (javac) log_result2 (jit) passes regression test?
>> ia32+OpenJDK Server VM (build 14.0-b16, mixed mode) 9.752490228984199 9.752490228984199 yes
>> arm+OpenJDK Shark VM (build 16.0-b13, mixed mode) 9.75249022898412 9.752490228984199 no
>> x86_64+OpenJDK 64-Bit Server VM (build 14.0-b16, mixed mode) 9.75249022898412 9.752490228984199 no
> The test applies to a bug which was fixed in hs17 so testing with hs14 is sure to fail on x86_64 which is where the bug was. The purpose of the test is to make sure that the value doesn't change over time which isn't allowed. In the original bug the compiler had an intrinsic for log but the interpreter wasn't using the same intrinsic so the interpreter and compiler could return different answers. So presumably if you test with hs17 x86_64 will be fine but I don't know what the problem would be with the ARM port of shark. Does it have intrinsics for Math.log?
Yes ARM port of Shark uses a intrinsic for the Shark JIT.
The Shark JIT uses the LLVM provided math intrinsics for log calculations,
and the Shark Interpreter Zero lets the Math.log class method handle it
and the class in turn uses the StrictMath.log JNI c call internally.
The reason why I get different results are of course because i use two
different implementations yet mathematically both valid approximations
> Also note that javac isn't producing the constant value since it's doesn't constant fold Math.log, let alone any other Math or StrictMath call. That value is computed by the class initializer which will run in the interpreter.
Thanks again for this heads up that the static value are calculated at
runtime by the interpreter and not constant folded, it makes the problem
We do now have enough information to sort out the bug
by making the Shark JIT call the same intrinsic as the StrictMath c
library provides, or the other way around.
Cheers and have a great day!
>> While trying to figure out whats the correct result for the log(17197) calculation i tested what StrictMath.log outputs:
>> StrictMath.log(17197) = 9.75249022898412
>> And in order to get an independent mathematically correct opinion of what log(17197) equals i asked wolfram alpha:
>> log(17197) = 9.7524902289841994797298917760120602447583441794533189705223...
>> or in short 9.752490228984199
>> So we have a situation where javac, jit, Math and StrictMath generates inconsistent results.
>> How do we resolve this situation?
>> Quoting the Math package java doc:
>> "If a method always has an error less than 0.5 ulps, the method always
>> returns the floating-point number nearest the exact result; such a
>> method is correctly rounded. A correctly rounded method is
>> generally the best a floating-point approximation can be; however,
>> it is impractical for many floating-point methods to be correctly
>> rounded. Instead, for the Math class, a larger error
>> bound of 1 or 2 ulps is allowed for certain methods"
>> Would this quotation imply that both log(17197) calculation results above are correct ( 9.752490228984199 and 9.75249022898412 )?
>> If both calculations are correct then I propose that we should change the hotspot/test/compiler/6539464 jtreg regression test to make all
>> JVM's pass the test when they are within +- 1 ulps from the mathematically correct answer of:
>> Cheers and have a great day!
More information about the jdk6-dev