By default, floating point operations on float
and double
do not strictly adhere to the rules of the IEEE 754 specification. An expression is allowed to use implementation-specific extensions to the range of these values; essentially allowing them to be more accurate than required.
strictfp
disables this behavior. It is applied to a class, interface, or method, and applies to everything contained in it, such as classes, interfaces, methods, constructors, variable initializers, etc. With strictfp
, the intermediate values of a floating-point expression must be within the float value set or the double value set. This causes the results of such expressions to be exactly those that the IEEE 754 specification predicts.
All constant expressions are implicitly strict, even if they aren't inside a strictfp
scope.
Therefore, strictfp
has the net effect of sometimes making certain corner case computations less accurate, and can also make floating point operations slower (as the CPU is now doing more work to ensure any native extra precision does not affect the result). However, it also causes the results to be exactly the same on all platforms. It is therefore useful in things like scientific programs, where reproducibility is more important than speed.
public class StrictFP { // No strictfp -> default lenient
public strictfp float strict(float input) {
return input * input / 3.4f; // Strictly adheres to the spec.
// May be less accurate and may be slower.
}
public float lenient(float input) {
return input * input / 3.4f; // Can sometimes be more accurate and faster,
// but results may not be reproducable.
}
public static final strictfp class Ops { // strictfp affects all enclosed entities
private StrictOps() {}
public static div(double dividend, double divisor) { // implicitly strictfp
return dividend / divisor;
}
}
}