Search code examples
javafloating-pointjls

Why is the conversion in non-strictfp mode considered as the one losing information?


I understand the conversion in strictfp mode is used for portability, not for accuracy as noted in this question. However, The Java Language Specification, Java SE 8 Edition says that

A widening primitive conversion from float to double that is not strictfp may lose information about the overall magnitude of the converted value.

which sounds to me that a widening primitive conversion that is strictfp is intended for accuracy. Furthermore, I suspect that double can represent literally all the values that float can take, in which I see no reason why a conversion from float to double is an issue here.

EDIT:

The wording "... may lose information about..." in the spec gave me a feeling of the conversion in non-strictfp mode lakcing some kind of accuracy as compared to that in strictfp mode. It did not make sense to me because the conversion in non-strictfp mode possibly makes use of intermediate values in higher precision. This question was first written based on this understanding, and might not look as desirable as you expected.


Solution

  • Intel's IA64 architecture uses a fixed floating point register format, one sign bit, 17 exponent bits, and 64 significand bits. When a floating point number is stored from one of those registers into a 32 or 64 bit variable, it has to be converted.

    Java aims for consistent results, so it is undesirable for the value of an expression to change depending on whether an intermediate result was held in a register or as an in-memory float or double.

    Originally, Java simply insisted on all calculations being done as though all intermediate results were stored. That turned out to give poor performance due to the difficulty of forcing the exponent into the right range on each calculation. The solution was to give the programmer the choice between a fully consistent strictfp mode, and a more relaxed mode in which an exponent could go outside the range for the expression type without the value being forced to a zero or infinity.

    Suppose, in relaxed mode, an in-register float has an exponent outside the double exponent range, and is being converted to an in-memory double. That conversion will force the value to a zero or infinity, losing its magnitude. That is an exception to the general rule that widening arithmetic conversions preserve the overall magnitude.

    If the same calculation were done in strictfp mode, the float would not have been allowed to have an exponent outside the float exponent range. Whatever calculation generated it would have forced the value to a zero or infinity. Every float value is exactly representable in double, so the conversion does not change the value at all, let alone losing the overall magnitude.