I'm using Java in an application running on multiple machines, and all machines need to get the same results for mathematical operations. Is it safe to use Java's floating point primitives? Or should I just use a fixed-point math library?
-
11No, it is not safe. Use `BigDecimal` instead or a math library that could help you solve this. – Luiggi Mendoza Mar 11 '14 at 19:44
-
_Why_ do you need to get exactly the same results on all machines? What type of calculations are you doing? – Clockwork-Muse Mar 12 '14 at 12:43
-
2possible duplicate of [When should I use the "strictfp" keyword in java?](http://stackoverflow.com/questions/517915/when-should-i-use-the-strictfp-keyword-in-java) – Raedwald Mar 14 '14 at 08:12
-
1Networked game-the same game model is running on every machine, input is sent across the network then input into the model, and for the games to remain in sync then every math operation must come out the same. Similar games have run into problems with using floating point... – Eamonn M.R. Mar 18 '14 at 19:20
-
Why are you using something that is by nature imprecise (floating point) to implement something that requires strict synchronization over a distributed framework? Should you think about your implementation instead of trying to get floating point to do something that it is not designed to do? – Stephen Chung Mar 19 '14 at 04:47
3 Answers
Not in general, no. However, you can use strictfp
expressions:
Within an FP-strict expression, all intermediate values must be elements of the float value set or the double value set, implying that the results of all FP-strict expressions must be those predicted by IEEE 754 arithmetic on operands represented using single and double formats.
Within an expression that is not FP-strict, some leeway is granted for an implementation to use an extended exponent range to represent intermediate results; the net effect, roughly speaking, is that a calculation might produce "the correct answer" in situations where exclusive use of the float value set or double value set might result in overflow or underflow.
-
So if I declare my main method strictfp, the entire program should work correctly? Or does every individual method or expression have to be declared strictfp? – Eamonn M.R. Mar 23 '14 at 21:14
-
@Eamonn: I can't say I've used strictfp myself, but I believe you need to do it on each method. – Jon Skeet Mar 23 '14 at 21:16
In addition to strictfp
, there's also StrictMath
which requires that the results be predictable for transcendental and other functions.

- 31,309
- 3
- 58
- 84
-
11+1 for mentioning StrictMath. Note that even though most methods in Math seem to simply delegate to StrictMath, many of those are silently replaced by JVM intrinsics at runtime. Intrinsics are platform specific. – ntoskrnl Mar 11 '14 at 23:04
-
3@ntoskrnl could you point me to a reference or further reading on that? – dimo414 Mar 11 '14 at 23:40
-
@dimo414 This question answers that better that I could: http://stackoverflow.com/questions/4232231/whats-the-difference-between-java-lang-math-and-java-lang-strictmath – ntoskrnl Mar 12 '14 at 13:42
The JVM should implement the IEEE specification consistently and this specification is very technical and precise. The floating point primitives of float and double are the same on all platforms.
The difference is only in the treatment of intermediate results, and that the virtual machine implementation may use float-extended-exponent and double-extended-exponent formats while evaluating expressions involving locals within the same frame of execution.
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 a strictfp context, it is possible that you will have differences across different JVMs at runtime. This is because in the evaluation of the expression d1*d2/d3 the intermediate result of d1*d2 is used in the expression "intermediate result"/d3 and the JVM might be using float-extended-exponent and double-extended-exponent formats to store the "intermediate result".
To get around this, you can use strictfp or StrictMath as others have answered here, OR avoid using intermediate results in your expressions. One way to do that is to store any intermediate result on the heap. For instance 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);
}
}

- 4,442
- 5
- 39
- 63
-
Are you sure that absence of `strictfp` allows the printed result to be different **for the particular values of d1, d2 and d3 in your example**? According to the paragraph quoted in Jon Skeet's answer, the result would have to be the same as the `strictfp` result for these values of d1, d2 and d3 because no underflow or overflow occurs in this particular computation. – Pascal Cuoq Mar 18 '14 at 16:21
-
In other words, the paragraph in Jon's answer only mentions extended exponent range, not “extended precision”. – Pascal Cuoq Mar 18 '14 at 16:22
-
@PascalCuoq My intention with the above sample code was solely to demonstrate what intermediate results were and how you can avoid side-effects by controlling how the VM will treat them. To answer your question, no, not a lot of thought or care went into selecting the *particular* values of d1 d2 d3 in the example. None of the virtual machines I have actually support IEEE 754 single extended and double extended formats as far as I am able to verify so I am not able to actually show this effect in action. – Mishax Mar 18 '14 at 16:50
-
@PascalCuoq I've also removed references to "extended precision", thanks for pointing that out – Mishax Mar 18 '14 at 16:56