Will floating point operations on the JVM produce the same results on all platforms?

I use Java in an application running on multiple machines, and all machines should get the same results for mathematical operations. Is it safe to use Java floating point primitives? Or should I just use a fixed point math library?

+56
java floating-point
Mar 11 '14 at 19:43
source share
3 answers

In general, no. However, you can use strictfp expressions :

Within the framework of a strict FP expression, all intermediate values ​​must be elements of a set float value or a double value, meaning that the results of all strongly expressed FP expressions must be predicted by IEEE 754 arithmetic for operands represented using single and double formats.

In an expression that is not FP-strict, there is some freedom of implementation to use an extended range of exponents to represent intermediate results; roughly speaking, the net effect is that the calculation can lead to a β€œcorrect answer” in situations where the exclusive use of a floating-point or double value can lead to overflow or overflow.

+56
Mar 11 '14 at 19:46
source share

In addition to strictfp also StrictMath , which requires that the results be predictable for transcendental and other functions.

+27
Mar 11 '14 at 19:57
source share

The JVM must consistently comply with the IEEE specification, and this specification is very technical and accurate. Float and double primitives are the same on all platforms.

The difference is only in the processing of intermediate results and that the virtual machine implementation can use formats with the extensions float-extended-exponent and double-extended-exponent when evaluating expressions involving local users in the same execution frame.

So, if you have code like:

 double d1 = 0.342; double d2 = 1.328479; double d3 = 4.99384728796; System.out.println(d1 * d2 / d3); 

and this is not in the context of strictfp, it is possible that at runtime you will have differences between different JVMs. This is due to the fact that when evaluating the expression d1 * d2 / d3, the intermediate result d1 * d2 is used in the expression "intermediate result" / d 3, and the JVM can use formats with the extension float-extended-exponent and double-extended-exponent for storage "interim result".

To get around this, you can use strictfp or StrictMath, as others answered here, or avoid using intermediate results in your expressions. One way to do this is to store any intermediate result on the heap. For example, as follows:

 class MyClass { static double d1 = 0.342; static double d2 = 1.328479; static double d3 = 4.99384728796; static double intermediate_result = 0d; public static void main(String[] args) { intermediate_result = d1 * d2; System.out.println(intermediate_result / d3); } } 
+9
Mar 12 '14 at 4:23
source share



All Articles