-
Bug
-
Resolution: Fixed
-
P4
-
14
The following sentences from JLS 3.10.2 "Floating-Point Literals" aren't entirely accurate:
The largest positive finite literal of type float is 3.4028235e38f.
The smallest positive finite non-zero literal of type float is 1.40e-45f.
The largest positive finite literal of type double is 1.7976931348623157e308.
The smallest positive finite non-zero literal of type double is 4.9e-324.
Each floating-point value, including the minimum and maximum values for the `float` and `double` types, has a region of the real number line which rounds to that value. The region depends on the rounding mode; for round-to-nearest, the region is usually one ulp wide and centered on the value. (The region is *not* centered for powers of two since the spacing between floating-point numbers changes at those boundaries.)
So, in the common case, the region (value - 0.5*ulp, value + 0.5*ulp) rounds to value; whether or not the exact halfway point rounds to value or to one of its neighbors depends on whether the value is odd or even in the destination format with respect to the round-to-nearest policy. Accordingly, the statement:
The largest positive finite literal of type float is 3.4028235e38f.
is strictly speaking not accurate in the following sense: there are literals which denote (prior to rounding) a larger exact numerical value than 3.4028235e38f, and which will ultimately denote (after rounding) the value Float.MAX_VALUE. The value of Float.MAX_VALUE + 0.5 * ulp(Float.MAX_VALUE) is:
340282356779733661637539395458142568448
Therefore, literals which are slightly smaller than this value, such as:
340282356779733661637539395458142568447f.9999...
340282356779733661637539395458142568447f.999
340282356779733661637539395458142568447f.99
340282356779733661637539395458142568447f.9
340282356779733661637539395458142568447f
will all round to Float.MAX_VALUE, and yet are all larger than 3.4028235e38f.
As a matter of interest, the lower bound of values that will round to Float.MAX_VALUE is:
340282336497324057985868971510891282432
A reasonable assumption is that 3.10.2 intends to list the "canonical" decimal values, which are the shortest strings that will round to the value in question. Separately, the value listed for the smallest float is *not* the shortest since it contains an extraneous trailing zero. With that as background, I propose the the following replacement text:
--------
The largest positive finite float value is numerically equal to (2-(2^-23))·2^127.
The shortest decimal literal which rounds to this value is 3.4028235e38f.
A hexadecimal literal for this value is 0x1.fffffeP+127f.
The smallest positive finite non-zero float value is numerically equal to 2^-149.
The shortest decimal literal which rounds to this value is 1.4e-45f.
Two hexadecimal literals for this value are 0x0.000002P-126f and 0x1.0P-149f.
The largest positive finite double value is numerically equal to (2-(2^-52))·2^1023.
The shortest decimal literal which rounds to this value is 1.7976931348623157e308.
A hexadecimal literal for this value is0x1.f_ffff_ffff_ffffP+1023.
The smallest positive finite non-zero double value is numerically equal to 2^-1074.
The shortest decimal literal which rounds to this value is 4.9e-324.
Two hexadecimal literals for this value are 0x0.0_0000_0000_0001P-1022 and 0x1.0P-1074.
--------
The new listing of the hex values imply ties to the properties of IEEE 754 format. For example, the maximum exponent for a double is 1023, the significand is 52 bits wide (plus a hidden bit), which corresponds to 13 hex digits (the substring f_ffff_ffff_ffff in 0x1.f_ffff_ffff_f02fffP+1023.). Two hex literals are given for the minimum values, one emphasizing the bit-level representation (all zero significand and min logical exponent 0x0.0_0000_0000_0001P-1022) and the other the numerical value ( 2^-1074 as 0x1.0p-1074).
The largest positive finite literal of type float is 3.4028235e38f.
The smallest positive finite non-zero literal of type float is 1.40e-45f.
The largest positive finite literal of type double is 1.7976931348623157e308.
The smallest positive finite non-zero literal of type double is 4.9e-324.
Each floating-point value, including the minimum and maximum values for the `float` and `double` types, has a region of the real number line which rounds to that value. The region depends on the rounding mode; for round-to-nearest, the region is usually one ulp wide and centered on the value. (The region is *not* centered for powers of two since the spacing between floating-point numbers changes at those boundaries.)
So, in the common case, the region (value - 0.5*ulp, value + 0.5*ulp) rounds to value; whether or not the exact halfway point rounds to value or to one of its neighbors depends on whether the value is odd or even in the destination format with respect to the round-to-nearest policy. Accordingly, the statement:
The largest positive finite literal of type float is 3.4028235e38f.
is strictly speaking not accurate in the following sense: there are literals which denote (prior to rounding) a larger exact numerical value than 3.4028235e38f, and which will ultimately denote (after rounding) the value Float.MAX_VALUE. The value of Float.MAX_VALUE + 0.5 * ulp(Float.MAX_VALUE) is:
340282356779733661637539395458142568448
Therefore, literals which are slightly smaller than this value, such as:
340282356779733661637539395458142568447f.9999...
340282356779733661637539395458142568447f.999
340282356779733661637539395458142568447f.99
340282356779733661637539395458142568447f.9
340282356779733661637539395458142568447f
will all round to Float.MAX_VALUE, and yet are all larger than 3.4028235e38f.
As a matter of interest, the lower bound of values that will round to Float.MAX_VALUE is:
340282336497324057985868971510891282432
A reasonable assumption is that 3.10.2 intends to list the "canonical" decimal values, which are the shortest strings that will round to the value in question. Separately, the value listed for the smallest float is *not* the shortest since it contains an extraneous trailing zero. With that as background, I propose the the following replacement text:
--------
The largest positive finite float value is numerically equal to (2-(2^-23))·2^127.
The shortest decimal literal which rounds to this value is 3.4028235e38f.
A hexadecimal literal for this value is 0x1.fffffeP+127f.
The smallest positive finite non-zero float value is numerically equal to 2^-149.
The shortest decimal literal which rounds to this value is 1.4e-45f.
Two hexadecimal literals for this value are 0x0.000002P-126f and 0x1.0P-149f.
The largest positive finite double value is numerically equal to (2-(2^-52))·2^1023.
The shortest decimal literal which rounds to this value is 1.7976931348623157e308.
A hexadecimal literal for this value is0x1.f_ffff_ffff_ffffP+1023.
The smallest positive finite non-zero double value is numerically equal to 2^-1074.
The shortest decimal literal which rounds to this value is 4.9e-324.
Two hexadecimal literals for this value are 0x0.0_0000_0000_0001P-1022 and 0x1.0P-1074.
--------
The new listing of the hex values imply ties to the properties of IEEE 754 format. For example, the maximum exponent for a double is 1023, the significand is 52 bits wide (plus a hidden bit), which corresponds to 13 hex digits (the substring f_ffff_ffff_ffff in 0x1.f_ffff_ffff_f02fffP+1023.). Two hex literals are given for the minimum values, one emphasizing the bit-level representation (all zero significand and min logical exponent 0x0.0_0000_0000_0001P-1022) and the other the numerical value ( 2^-1074 as 0x1.0p-1074).
- relates to
-
JDK-7074799 4.2: Adopt IEEE 754-2019 terminology in JLS
- Resolved