From alex.buckley at oracle.com Fri Oct 18 17:54:10 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 18 Oct 2019 10:54:10 -0700 Subject: JLS 3.9 -- Role of underscore Message-ID: The following issue was raised on the java-se-spec-comments list: https://mail.openjdk.java.net/pipermail/java-se-spec-comments/2019-October/000003.html "In the Java Language Specification JSE13 Edition, 3.9 Keywords, the paragraph that explains const and goto are "reserved but not currently used" should also mention the underscore (_) keyword. As far as I can tell, it is "not currently used" either, with the intent being to eventually have it indicate an unused lambda, method, or catch formal parameter in a declaration (JEP 302: Lambda Leftovers)." 3.9 should indeed call out the underscore keyword as reserved, and summarize the policy from JEP 302, which I record here for convenience: ----- Treatment of underscores In many languages, it is common to use an underscore (_) to denote an unnamed lambda parameter (and similarly for method and exception parameters): BiFunction biss = (i, _) -> String.valueOf(i); This allows stronger static checking of unused arguments, and also allows multiple arguments to be marked as unused. However, because underscore was a valid identifier as of Java 8, compatibility required us to take a more indirect path to getting to where underscore could serve this role in Java. Phase 1 was forbidding underscore as a lambda formal parameter name in Java 8 (this had no compatibility consequence, since lambdas did not exist previously) and a warning was issued for using underscore as an identifier in other places. Phase 2 came in Java 9, when this warning became an error. We are now free to complete the planned rehabilitation of underscore to indicate an unused lambda, method, or catch formal parameter. ----- Alex From alex.buckley at oracle.com Fri Oct 18 18:12:44 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 18 Oct 2019 11:12:44 -0700 Subject: JLS 3.10.4 -- Unicode escape for apostrophe Message-ID: <8f260e8e-05ed-8ab4-0ea1-574693858d8f@oracle.com> The following issue was raised on the java-se-spec-comments list: https://mail.openjdk.java.net/pipermail/java-se-spec-comments/2019-October/000004.html "In the Java Language Specification JSE13 Edition, 3.10.4, Character Literals, the next to last paragraph needs an additional sentence: "Finally, it is not possible to write '\u0027' for a character literal containing an apostrophe (').". To be helpful, and to align with a similar sentence in 3.10.5, 3.10.4 should indeed add the sentence above to the informative paragraph which currently ends "Instead, use '\r'." Alex From alex.buckley at oracle.com Fri Oct 18 18:28:38 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 18 Oct 2019 11:28:38 -0700 Subject: JLS 3.10.2 -- Exposition of hexadecimal f.p. literals Message-ID: <3fd4ecd5-473c-9189-de2e-b580df59c267@oracle.com> The following issue was raised on the java-se-spec-comments list: https://mail.openjdk.java.net/pipermail/java-se-spec-comments/2019-October/000003.html ----- In 3.10.2, Floating-Point Literals, hexadecimal floating-point literals are poorly explained. It is not mentioned that the "binary exponent" part is in base 2 instead of the decimal floating-point exponent base 10. An example would be useful. Something like "0xFFp1 = 510.0". It is also somewhat unclear if hexadecimal floating-point literals are double- or single-precision by default. The first text paragraph of page 36 could clear this up if changed from "A floating-point literal is of type float [...]" to "A floating-point literal (decimal or hexadecimal) is of type float [...]". The values for the largest/smallest positive finite non-zero float/double literals should also be given in hexadecimal notation and include mention of the predefined constants MIN_VALUE and MAX_VALUE of the Float and Double classes. Finally, on page 37 the reference to "a non-zero denormalized number" should add "(see 4.2.3)". ----- These are largely issues of editorial clarity, not correctness. I defer to Joe Darcy to decide whether, 15 years after hexadecimal f.p. literals were added to the JLS (Third Edition, for Java SE 5), it is worth trying to incorporate/update material from https://blogs.oracle.com/darcy/hexadecimal-floating-point-literals into JLS 3.10.2. Alex From alex.buckley at oracle.com Fri Oct 18 19:21:53 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 18 Oct 2019 12:21:53 -0700 Subject: JLS - "anywhere within" static initializer In-Reply-To: <091FE45216766B4689D1F05C421CF18363C7DF24@exch-mb-l4-01.campus.aston.ac.uk> References: <091FE45216766B4689D1F05C421CF18363C7DF24@exch-mb-l4-01.campus.aston.ac.uk> Message-ID: <33222104-91a2-162a-0dd4-56f7720acf52@oracle.com> On 8/17/2018 11:35 AM, Kay, Andrew (Research Student) wrote: > I've noticed something slightly misleading in the JLS, section 8.7 > (Static Initializers): > > It is a compile-time error if a return statement> (?14.17) appears > anywhere within a static initializer. ... > This could be resolved by adding something like "?anywhere within a > static initializer, unless it appears within a local class > declaration contained in that static initializer". There are at least > two more cases which should be permitted - anonymous class > declarations, and return statements in lambda body blocks. /* Note that a similar situation arises in 8.6 -- "It is a compile-time error if a return statement (?14.17) appears anywhere within an instance initializer." -- and 8.3.2 -- "It is a compile-time error if the keyword this (?15.8.3) or the keyword super (?15.11.2, ?15.12) occurs in the [variable] initializer.". */ The JLS text is accurate, but not precise. Precisely characterizing the context where something appears is hard: formal grammar-driven descriptions of enclosing and enclosed contexts are tough to understand, while informal narrative descriptions inevitably bring their own incongruities. For example, under the narrative rule "... unless it appears within a local class declaration contained in that static initializer", the code below is legal only because in judging that the `return` "appears within a local class declaration", you somehow know to treat the immediately enclosing method declaration as if it was invisible: class A { static { class B { int m() { return 5; } } } } But now someone else will say the rule should be: "... unless it appears within a method declaration of a local class declaration contained in that static initializer". Add in a sub-clause for "the body of a lambda expression" etc, and now the qualifying "unless" clause is longer than the main "compile-time error" clause. I tend to think of the JLS' traditional phrasing in 8.3.2, 8.6, and 8.7 as delivering 90% of the precision for a fraction of the cost (i.e. burden on the reader) that delivering 100% would require. I concede that the word "anywhere" is a potential source of trouble. I believe it was aiming for the sense of "anywhere within the Block of the instance initializer -- you can't have a `return` statement directly enclosed by the Block OR enclosed by other statements within the Block". That's an important rule in itself. On balance, I don't see much benefit from tweaking the narration here. Alex From joe.darcy at oracle.com Thu Oct 24 20:38:05 2019 From: joe.darcy at oracle.com (Joe Darcy) Date: Thu, 24 Oct 2019 13:38:05 -0700 Subject: JLS 3.10.2 -- Exposition of hexadecimal f.p. literals In-Reply-To: <3fd4ecd5-473c-9189-de2e-b580df59c267@oracle.com> References: <3fd4ecd5-473c-9189-de2e-b580df59c267@oracle.com> Message-ID: <5638cdef-e225-69af-f3b7-81a2cc29dc6e@oracle.com> Hello, Catching up on email... On 10/18/2019 11:28 AM, Alex Buckley wrote: > The following issue was raised on the java-se-spec-comments list: > > https://mail.openjdk.java.net/pipermail/java-se-spec-comments/2019-October/000003.html > > > ----- > In 3.10.2, Floating-Point Literals, hexadecimal floating-point > literals are poorly explained. It is not mentioned that the "binary > exponent" part is in base 2 instead of the decimal floating-point > exponent base 10. An example would be useful. Something like "0xFFp1 = > 510.0". > > It is also somewhat unclear if hexadecimal floating-point literals are > double- or single-precision by default. The first text paragraph of > page 36 could clear this up if changed from "A floating-point literal > is of type float [...]" to "A floating-point literal (decimal or > hexadecimal) is of type float [...]". > > The values for the largest/smallest positive finite non-zero > float/double literals should also be given in hexadecimal notation and > include mention of the predefined constants MIN_VALUE and MAX_VALUE of > the Float and Double classes. > > Finally, on page 37 the reference to "a non-zero denormalized number" > should add "(see 4.2.3)". > ----- > > These are largely issues of editorial clarity, not correctness. I > defer to Joe Darcy to decide whether, 15 years after hexadecimal f.p. > literals were added to the JLS (Third Edition, for Java SE 5), it is > worth trying to incorporate/update material from > https://blogs.oracle.com/darcy/hexadecimal-floating-point-literals > into JLS 3.10.2. > FWIW, javadoc of the Double.toHexString method does have a more detailed description of the double value to hex-string mapping. However, it would be an aid to readers of the JLS to include a bit more exposition about hexadecimal floating-point literals. For example, in the API spec Double.MAX_VALUE is listed as its numerical value ((2-2^-52 )?2^1023 ), as a decimal floating-point value, and as a hexadecimal floating-point value (0x1.fffffffffffffP+1023): https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/lang/Double.html#MAX_VALUE Analogous text could be included for the JLS discussion of the min and max values of float and double. To make an explicit statement about the value of a floating-point literal, I suggest after the sentence "A floating-point literal may be expressed in decimal (base 10) or hexadecimal (base 16). " adding something like "The exact numerical value of a decimal floating-point literals is ??? decimal_sequence * 10 ^ exponent The exact numerical value of a hexadecimal floating-point literal is ??? hex_sequence * 2 ^ exponent The conversion of the exact numerical value to a particular floating-point value is handled as if by Float.valueOf or Double.valueOf for literals of type float and double, respectively." HTH, -Joe From alex.buckley at oracle.com Fri Oct 25 00:04:38 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 24 Oct 2019 17:04:38 -0700 Subject: JLS 3.10.2 -- Exposition of hexadecimal f.p. literals In-Reply-To: <5638cdef-e225-69af-f3b7-81a2cc29dc6e@oracle.com> References: <3fd4ecd5-473c-9189-de2e-b580df59c267@oracle.com> <5638cdef-e225-69af-f3b7-81a2cc29dc6e@oracle.com> Message-ID: <9319a51b-1f03-c2de-1cb7-650beabb11c8@oracle.com> On 10/24/2019 1:38 PM, Joe Darcy wrote: > To make an explicit statement about the value of a floating-point > literal, I suggest after the sentence > > "A floating-point literal may be expressed in decimal (base 10) or > hexadecimal (base 16). " > > adding something like > > "The exact numerical value of a decimal floating-point literals is > > ??? decimal_sequence * 10 ^ exponent > > The exact numerical value of a hexadecimal floating-point literal is > > ??? hex_sequence * 2 ^ exponent > > The conversion of the exact numerical value to a particular > floating-point value is handled as if by Float.valueOf or Double.valueOf > for literals of type float and double, respectively." This is a good start, but needs tightening up. Please consider this text as if you're seeing it for the first time, bearing in mind that it's defining terms which map to productions in the grammar immediately after. ----- A floating-point literal may be expressed in decimal (base 10) or hexadecimal (base 16). For decimal floating-point literals, at least one digit (in either the whole number or the fraction part) and either a decimal point, an exponent, or a float type suffix are required. All other parts are optional. The exponent, if present, is indicated by the ASCII letter e or E followed by an optionally signed integer. The exact numerical value of a decimal floating-point literal is: decimal_sequence * 10 ^ exponent For hexadecimal floating-point literals, at least one digit is required (in either the whole number or the fraction part), and the exponent is mandatory, and the float type suffix is optional. The exponent is indicated by the ASCII letter p or P followed by an optionally signed integer. The exact numerical value of a hexadecimal floating-point literal is: hex_sequence * 2 ^ exponent Underscores are allowed as separators between digits that denote the whole-number part, and between digits that denote the fraction part, and between digits that denote the exponent. ----- - What is "decimal_sequence"? The answer must be in terms of the artifacts mentioned in the immediately preceding paragraph -- or modify the grammar to introduce new artifacts that can be described in the narrative. - Similarly for "hex_sequence". - A decimal f-p literal need not include the exponent part, so the definition can't just assume "exponent" is known. - For a hexadecimal f-p literal, the questioner mentioned that the (mandatory) exponent is "in base 2", but there is no requirement to write the exponent in binary. There's lots of potential for confusion here. What are some examples of hexadecimal f-p literals? In the JLS, it is often the most fundamental descriptions and operations that are the hardest to phrase. We're not there yet for f-p literal values. Alex From joe.darcy at oracle.com Sat Oct 26 00:29:17 2019 From: joe.darcy at oracle.com (Joe Darcy) Date: Fri, 25 Oct 2019 17:29:17 -0700 Subject: JLS 3.10.2 -- Exposition of hexadecimal f.p. literals In-Reply-To: <9319a51b-1f03-c2de-1cb7-650beabb11c8@oracle.com> References: <3fd4ecd5-473c-9189-de2e-b580df59c267@oracle.com> <5638cdef-e225-69af-f3b7-81a2cc29dc6e@oracle.com> <9319a51b-1f03-c2de-1cb7-650beabb11c8@oracle.com> Message-ID: <300223e4-cb86-b77f-c114-852772533ff0@oracle.com> To provide some additional background on this thread if not the JLS section in question, hexadecimal floating-point literals are a very useful language feature for a narrow range of situations. Those situations include having a straightforward way to set the exact bits of a floating-point value using a roughly human readable format. I commonly use hexadecimal floating-point literals in numerical tests and have added them to the narrative specs for sentinel values such as Double.MAX_VALUE. A finite IEEE floating-point value is conceptually a tuple of three values, sign, significand, and exponent, where the significand and exponent have ranges that are a function of the format in question, float or double, etc. Depending on how one wants to formulate the values, the ranges of each of these values can be given in terms of a set of contiguous integers. In a hex floating-point literal, the significand value is written in hex but the exponent value is written in *decimal*. However, the decimal value is used as an exponent for base 2 and in that sense is a "binary" exponent. This seemingly conflicting design works for the intended use cases. For example, the smallest nonzero double value is numerically equal to 2^-1074. As a hex literal this can be written in a number of ways including ??? 0x1.0p-1074 in decimal, 1 * 2 ^ -1074. The way to write the value corresponding to the representation of the floating-point value, using some underscores to help grouping, is ??? 0x0.0000_0000_0000_1p-1022 Decoding, this is a subnormal value (leading digit 0 with the lowest exponent value) and only the least significant bit of the significand is set. The double format uses 52-bits for its significand field, 13 hex digits. Other examples would include how to write "3.0" in a way corresponding to the representation: ??? 0x1.8p1 that is 1.8 as a hex value (namely 1.5 in decimal) multiplied by 2^1 = 2. On 10/24/2019 5:04 PM, Alex Buckley wrote: > On 10/24/2019 1:38 PM, Joe Darcy wrote: >> To make an explicit statement about the value of a floating-point >> literal, I suggest after the sentence >> >> "A floating-point literal may be expressed in decimal (base 10) or >> hexadecimal (base 16). " >> >> adding something like >> >> "The exact numerical value of a decimal floating-point literals is >> >> ???? decimal_sequence * 10 ^ exponent >> >> The exact numerical value of a hexadecimal floating-point literal is >> >> ???? hex_sequence * 2 ^ exponent >> >> The conversion of the exact numerical value to a particular >> floating-point value is handled as if by Float.valueOf or >> Double.valueOf for literals of type float and double, respectively." > > This is a good start, but needs tightening up. Please consider this > text as if you're seeing it for the first t To be more explicit, "decimal_sequence * 10 ^ exponent " is an informal short-hand for "in each of the possible decimal floating-point literal forms below, collect together the leading digits as a digit sequence, treat it as a normal rational numerical value and multiply it by 10 raised to the exponent where the exponent if implicitly 1 if not syntactically present in the literal." ???? Digits . [Digits] [ExponentPart] [FloatTypeSuffix] ??? . Digits [ExponentPart] [FloatTypeSuffix] ??? Digits ExponentPart [FloatTypeSuffix] ??? Digits [ExponentPart] FloatTypeSuffix > ime, bearing in mind that it's defining terms which map to productions > in the grammar immediately after. > > ----- > A floating-point literal may be expressed in decimal (base 10) or > hexadecimal (base 16). > > For decimal floating-point literals, at least one digit (in either the > whole number or the fraction part) and either a decimal point, an > exponent, or a float type suffix are required. All other parts are > optional. The exponent, if present, is indicated by the ASCII letter e > or E followed by an optionally signed integer. > > The exact numerical value of a decimal floating-point literal is: > ? decimal_sequence * 10 ^ exponent > > For hexadecimal floating-point literals, at least one digit is > required (in either the whole number or the fraction part), and the > exponent is mandatory, and the float type suffix is optional. The > exponent is indicated by the ASCII letter p or P followed by an > optionally signed integer. > > The exact numerical value of a hexadecimal floating-point literal is: > ? hex_sequence * 2 ^ exponent > > Underscores are allowed as separators between digits that denote the > whole-number part, and between digits that denote the fraction part, > and between digits that denote the exponent. > ----- > > - What is "decimal_sequence"? The answer must be in terms of the > artifacts mentioned in the immediately preceding paragraph -- or > modify the grammar to introduce new artifacts that can be described in > the narrative. > > - Similarly for "hex_sequence". > > - A decimal f-p literal need not include the exponent part, so the > definition can't just assume "exponent" is known. > > - For a hexadecimal f-p literal, the questioner mentioned that the > (mandatory) exponent is "in base 2", but there is no requirement to > write the exponent in binary. There's lots of potential for confusion > here. What are some examples of hexadecimal f-p literals? > > In the JLS, it is often the most fundamental descriptions and > operations that are the hardest to phrase. We're not there yet for f-p > literal values. There could be value in having a highly condensed floating-point primer in the JLS, but it would be fine to continue to omit such information as well. For example, the statement in the JLS ??? "The smallest positive finite non-zero literal of type double is 4.9e-324." is considerably more subtle than it appears at first. All finite binary floating-point values are exactly representable as double values since 10 = 2 * 5. There is a range of the number line which converts to Double.MIN_VALUE and many decimal strings in that range which get converted to Double.MIN_VALUE. The string "4.9e-324" is not the numerically smallest such string nor is it the numerically largest. The exact string has several hundred decimal digits. This string used is the shortest such string, which is regarded as the canonical one. Such subtleties could be alluded to in the JLS; if there is interest, I could work on a few paragraphs describing the situation. Cheers, -Joe From alex.buckley at oracle.com Mon Oct 28 23:15:29 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 28 Oct 2019 16:15:29 -0700 Subject: JLS 3.10.2 -- Exposition of hexadecimal f.p. literals In-Reply-To: <300223e4-cb86-b77f-c114-852772533ff0@oracle.com> References: <3fd4ecd5-473c-9189-de2e-b580df59c267@oracle.com> <5638cdef-e225-69af-f3b7-81a2cc29dc6e@oracle.com> <9319a51b-1f03-c2de-1cb7-650beabb11c8@oracle.com> <300223e4-cb86-b77f-c114-852772533ff0@oracle.com> Message-ID: <38d7506e-91f1-177e-a48c-71d70b5606a3@oracle.com> Thanks Joe. I am unable to spend more time on this issue, so I have filed JDK-8233092 to record it for the future. Alex On 10/25/2019 5:29 PM, Joe Darcy wrote: > To provide some additional background on this thread if not the JLS > section in question, hexadecimal floating-point literals are a very > useful language feature for a narrow range of situations. Those > situations include having a straightforward way to set the exact bits of > a floating-point value using a roughly human readable format. I commonly > use hexadecimal floating-point literals in numerical tests and have > added them to the narrative specs for sentinel values such as > Double.MAX_VALUE. > > A finite IEEE floating-point value is conceptually a tuple of three > values, sign, significand, and exponent, where the significand and > exponent have ranges that are a function of the format in question, > float or double, etc. Depending on how one wants to formulate the > values, the ranges of each of these values can be given in terms of a > set of contiguous integers. > > In a hex floating-point literal, the significand value is written in hex > but the exponent value is written in *decimal*. However, the decimal > value is used as an exponent for base 2 and in that sense is a "binary" > exponent. This seemingly conflicting design works for the intended use > cases. > > For example, the smallest nonzero double value is numerically equal to > 2^-1074. As a hex literal this can be written in a number of ways including > > ??? 0x1.0p-1074 > > in decimal, 1 * 2 ^ -1074. The way to write the value corresponding to > the representation of the floating-point value, using some underscores > to help grouping, is > > ??? 0x0.0000_0000_0000_1p-1022 > > Decoding, this is a subnormal value (leading digit 0 with the lowest > exponent value) and only the least significant bit of the significand is > set. The double format uses 52-bits for its significand field, 13 hex > digits. > > Other examples would include how to write "3.0" in a way corresponding > to the representation: > > ??? 0x1.8p1 > > that is 1.8 as a hex value (namely 1.5 in decimal) multiplied by 2^1 = 2. > > On 10/24/2019 5:04 PM, Alex Buckley wrote: >> On 10/24/2019 1:38 PM, Joe Darcy wrote: >>> To make an explicit statement about the value of a floating-point >>> literal, I suggest after the sentence >>> >>> "A floating-point literal may be expressed in decimal (base 10) or >>> hexadecimal (base 16). " >>> >>> adding something like >>> >>> "The exact numerical value of a decimal floating-point literals is >>> >>> ???? decimal_sequence * 10 ^ exponent >>> >>> The exact numerical value of a hexadecimal floating-point literal is >>> >>> ???? hex_sequence * 2 ^ exponent >>> >>> The conversion of the exact numerical value to a particular >>> floating-point value is handled as if by Float.valueOf or >>> Double.valueOf for literals of type float and double, respectively." >> >> This is a good start, but needs tightening up. Please consider this >> text as if you're seeing it for the first t > > To be more explicit, "decimal_sequence * 10 ^ exponent " is an informal > short-hand for "in each of the possible decimal floating-point literal > forms below, collect together the leading digits as a digit sequence, > treat it as a normal rational numerical value and multiply it by 10 > raised to the exponent where the exponent if implicitly 1 if not > syntactically present in the literal." > > ???? Digits . [Digits] [ExponentPart] [FloatTypeSuffix] > ??? . Digits [ExponentPart] [FloatTypeSuffix] > ??? Digits ExponentPart [FloatTypeSuffix] > ??? Digits [ExponentPart] FloatTypeSuffix > > >> ime, bearing in mind that it's defining terms which map to productions >> in the grammar immediately after. >> >> ----- >> A floating-point literal may be expressed in decimal (base 10) or >> hexadecimal (base 16). >> >> For decimal floating-point literals, at least one digit (in either the >> whole number or the fraction part) and either a decimal point, an >> exponent, or a float type suffix are required. All other parts are >> optional. The exponent, if present, is indicated by the ASCII letter e >> or E followed by an optionally signed integer. >> >> The exact numerical value of a decimal floating-point literal is: >> ? decimal_sequence * 10 ^ exponent >> >> For hexadecimal floating-point literals, at least one digit is >> required (in either the whole number or the fraction part), and the >> exponent is mandatory, and the float type suffix is optional. The >> exponent is indicated by the ASCII letter p or P followed by an >> optionally signed integer. >> >> The exact numerical value of a hexadecimal floating-point literal is: >> ? hex_sequence * 2 ^ exponent >> >> Underscores are allowed as separators between digits that denote the >> whole-number part, and between digits that denote the fraction part, >> and between digits that denote the exponent. >> ----- >> >> - What is "decimal_sequence"? The answer must be in terms of the >> artifacts mentioned in the immediately preceding paragraph -- or >> modify the grammar to introduce new artifacts that can be described in >> the narrative. >> >> - Similarly for "hex_sequence". >> >> - A decimal f-p literal need not include the exponent part, so the >> definition can't just assume "exponent" is known. >> >> - For a hexadecimal f-p literal, the questioner mentioned that the >> (mandatory) exponent is "in base 2", but there is no requirement to >> write the exponent in binary. There's lots of potential for confusion >> here. What are some examples of hexadecimal f-p literals? >> >> In the JLS, it is often the most fundamental descriptions and >> operations that are the hardest to phrase. We're not there yet for f-p >> literal values. > > There could be value in having a highly condensed floating-point primer > in the JLS, but it would be fine to continue to omit such information as > well. For example, the statement in the JLS > > ??? "The smallest positive finite non-zero literal of type double is > 4.9e-324." > > is considerably more subtle than it appears at first. All finite binary > floating-point values are exactly representable as double values since > 10 = 2 * 5. There is a range of the number line which converts to > Double.MIN_VALUE and many decimal strings in that range which get > converted to Double.MIN_VALUE. The string "4.9e-324" is not the > numerically smallest such string nor is it the numerically largest. The > exact string has several hundred decimal digits. This string used is the > shortest such string, which is regarded as the canonical one. > > Such subtleties could be alluded to in the JLS; if there is interest, I > could work on a few paragraphs describing the situation. > > Cheers, > > -Joe >