I know the strictfp modifier strictfp for methods (and classes) according to JLS:
JLS 8.4.3.5, strictfp methods:
The effect of the strictfp modifier is to make all float or double expressions inside the method body must be explicitly FP-strict (§15.4).
JLS 15.4 Strict FP Expressions:
Within a strict FP expression, all intermediate values must be elements of a given float value or a double value, which means that the results of all FP strict expressions must be predicted by IEEE 754 arithmetic for operands represented using one or two formats.
In an expression that is not FP-strict, some freedom is provided for implementation to use an extended range of exhibitors to represent intermediate results; the net effect, roughly speaking, is that the calculation can lead to a “correct answer” in situations where the exclusive use of a set of float values or a double value can result in overflow or overflow.
I tried to come up with a way to get the real difference between the expression in the strictfp method and what is not strictfp . I tried this on two laptops, one with an Intel Core i3 processor and one with an Intel Core i7 processor. And I can’t understand.
Many reports suggest that a native floating point that does not use strictfp can use 80-bit floating-point numbers and have additional displayed numbers below the minimum possible double java (closest to zero) or above the maximum possible 64-bit java double.
I tried this code below with and without strictfp modifier, and it gives exactly the same results.
public static strictfp void withStrictFp() { double v = Double.MAX_VALUE; System.out.println(v * 1.0000001 / 1.0000001); v = Double.MIN_VALUE; System.out.println(v / 2 * 2); }
Actually, I assume that any difference will only be displayed when the code is compiled for assembly, so I run it with the -Xcomp JVM argument. But no difference.
I found another post explaining how you can get the assembly code generated by HotSpot ( OpenJDK Documentation ). I run my code with java -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly . The first expression ( v * 1.0000001 / 1.0000001 ) with the strictfp modifier, as well as without it, is compiled into:
0x000000010f10a0a9: movsd -0xb1(%rip),%xmm0
There is nothing in this code that trims the result of each step to 64 bits, as I expected. Documentation search movsd , mulsd and divsd , they all mention that these (SSE) commands work with 64-bit floating point values, and not with 80-bit values, as I expected. Therefore, it seems logical that the double value set by these instructions is already an IEEE 754 value, so there would be no difference between the presence of strictfp and the absence of it.
My questions:
- Is this analysis correct? I do not often use the Intel assembly, so I'm not sure of my conclusion.
- Is there any (other) modern processor architecture (with JVM) for which there is a difference between the operation with the
strictfp modifier and without it?