Details

Type: Bug

Status: Resolved

Priority: P4

Resolution: Fixed

Affects Version/s: 14

Fix Version/s: 15

Component/s: specification

Labels:

Subcomponent:
Description
The following sentences from JLS 3.10.2 "FloatingPoint Literals" aren't entirely accurate:
The largest positive finite literal of type float is 3.4028235e38f.
The smallest positive finite nonzero literal of type float is 1.40e45f.
The largest positive finite literal of type double is 1.7976931348623157e308.
The smallest positive finite nonzero literal of type double is 4.9e324.
Each floatingpoint 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 roundtonearest, 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 floatingpoint 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 roundtonearest 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 nonzero float value is numerically equal to 2^149.
The shortest decimal literal which rounds to this value is 1.4e45f.
Two hexadecimal literals for this value are 0x0.000002P126f and 0x1.0P149f.
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 nonzero double value is numerically equal to 2^1074.
The shortest decimal literal which rounds to this value is 4.9e324.
Two hexadecimal literals for this value are 0x0.0_0000_0000_0001P1022 and 0x1.0P1074.

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 bitlevel representation (all zero significand and min logical exponent 0x0.0_0000_0000_0001P1022) and the other the numerical value ( 2^1074 as 0x1.0p1074).
The largest positive finite literal of type float is 3.4028235e38f.
The smallest positive finite nonzero literal of type float is 1.40e45f.
The largest positive finite literal of type double is 1.7976931348623157e308.
The smallest positive finite nonzero literal of type double is 4.9e324.
Each floatingpoint 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 roundtonearest, 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 floatingpoint 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 roundtonearest 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 nonzero float value is numerically equal to 2^149.
The shortest decimal literal which rounds to this value is 1.4e45f.
Two hexadecimal literals for this value are 0x0.000002P126f and 0x1.0P149f.
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 nonzero double value is numerically equal to 2^1074.
The shortest decimal literal which rounds to this value is 4.9e324.
Two hexadecimal literals for this value are 0x0.0_0000_0000_0001P1022 and 0x1.0P1074.

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 bitlevel representation (all zero significand and min logical exponent 0x0.0_0000_0000_0001P1022) and the other the numerical value ( 2^1074 as 0x1.0p1074).
Attachments
Issue Links
 relates to

JDK7074799 4.2: Adopt IEEE 7542019 terminology in JLS
 Resolved