6476168: (fmt) Inconsistency formatting subnormal doubles with hexadecimal conversion

Update specification to match implementation.

Reviewed-by: darcy
This commit is contained in:
Brian Burkhalter 2013-07-31 10:53:33 -07:00 committed by Brian Burkhalter
parent 575679c789
commit 2c31d993a4
4 changed files with 107 additions and 43 deletions

View File

@ -626,12 +626,11 @@ import sun.misc.FormattedFloatingDecimal;
* <p> For general argument types, the precision is the maximum number of
* characters to be written to the output.
*
* <p> For the floating-point conversions {@code 'e'}, {@code 'E'}, and
* {@code 'f'} the precision is the number of digits after the decimal
* separator. If the conversion is {@code 'g'} or {@code 'G'}, then the
* <p> For the floating-point conversions {@code 'a'}, {@code 'A'}, {@code 'e'},
* {@code 'E'}, and {@code 'f'} the precision is the number of digits after the
* radix point. If the conversion is {@code 'g'} or {@code 'G'}, then the
* precision is the total number of digits in the resulting magnitude after
* rounding. If the conversion is {@code 'a'} or {@code 'A'}, then the
* precision must not be specified.
* rounding.
*
* <p> For character, integral, and date/time argument types and the percent
* and line separator conversions, the precision is not applicable; if a
@ -1297,14 +1296,21 @@ import sun.misc.FormattedFloatingDecimal;
* of the significand as a fraction. The exponent is represented by
* {@code 'p'} (<tt>'&#92;u0070'</tt>) followed by a decimal string of the
* unbiased exponent as if produced by invoking {@link
* Integer#toString(int) Integer.toString} on the exponent value.
* Integer#toString(int) Integer.toString} on the exponent value. If the
* precision is specified, the value is rounded to the given number of
* hexadecimal digits.
*
* <li> If <i>m</i> is a {@code double} value with a subnormal
* representation then the significand is represented by the characters
* {@code '0x0.'} followed by the hexadecimal representation of the rest
* of the significand as a fraction. The exponent is represented by
* {@code 'p-1022'}. Note that there must be at least one nonzero digit
* in a subnormal significand.
* representation then, unless the precision is specified to be in the range
* 1 through 12, inclusive, the significand is represented by the characters
* {@code '0x0.'} followed by the hexadecimal representation of the rest of
* the significand as a fraction, and the exponent represented by
* {@code 'p-1022'}. If the precision is in the interval
* [1,&nbsp;12], the subnormal value is normalized such that it
* begins with the characters {@code '0x1.'}, rounded to the number of
* hexadecimal digits of precision, and the exponent adjusted
* accordingly. Note that there must be at least one nonzero digit in a
* subnormal significand.
*
* </ul>
*
@ -1367,7 +1373,7 @@ import sun.misc.FormattedFloatingDecimal;
* {@code 1}.
*
* <p> If the conversion is {@code 'a'} or {@code 'A'}, then the precision
* is the number of hexadecimal digits after the decimal separator. If the
* is the number of hexadecimal digits after the radix point. If the
* precision is not provided, then all of the digits as returned by {@link
* Double#toHexString(double)} will be output.
*

View File

@ -1319,10 +1319,8 @@ public class Basic$Type$ extends Basic {
Math.nextDown(DoubleConsts.MIN_NORMAL));
test("%.1a", "0x1.0p-1022",
Math.nextDown(DoubleConsts.MIN_NORMAL));
test("%.11a", "0x1.ffffffffffep-1023",
Double.parseDouble("0x0.fffffffffffp-1022"));
test("%.1a", "0x1.0p-1022",
Double.parseDouble("0x0.fffffffffffp-1022"));
test("%.11a", "0x1.ffffffffffep-1023", 0x0.fffffffffffp-1022);
test("%.1a", "0x1.0p-1022", 0x0.fffffffffffp-1022);
test("%.30a", "0x0.000000000000100000000000000000p-1022", Double.MIN_VALUE);
test("%.13a", "0x0.0000000000001p-1022", Double.MIN_VALUE);
test("%.11a", "0x1.00000000000p-1074", Double.MIN_VALUE);
@ -1336,19 +1334,50 @@ public class Basic$Type$ extends Basic {
test("%.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE);
test("%.11a", "0x1.00000000000p1024", Double.MAX_VALUE);
test("%.1a", "0x1.0p1024", Double.MAX_VALUE);
test("%.11a", "0x1.18000000000p0", Double.parseDouble("0x1.18p0"));
test("%.1a", "0x1.2p0", Double.parseDouble("0x1.18p0"));
test("%.11a", "0x1.18000000000p0", 0x1.18p0);
test("%.1a", "0x1.2p0", 0x1.18p0);
test("%.11a", "0x1.18000000000p0",
Double.parseDouble("0x1.180000000001p0"));
test("%.1a", "0x1.2p0",
Double.parseDouble("0x1.180000000001p0"));
test("%.11a", "0x1.28000000000p0", Double.parseDouble("0x1.28p0"));
test("%.1a", "0x1.2p0", Double.parseDouble("0x1.28p0"));
test("%.11a", "0x1.18000000000p0", 0x1.180000000001p0);
test("%.1a", "0x1.2p0", 0x1.180000000001p0);
test("%.11a", "0x1.28000000000p0", 0x1.28p0);
test("%.1a", "0x1.2p0", 0x1.28p0);
test("%.11a", "0x1.28000000000p0", 0x1.280000000001p0);
test("%.1a", "0x1.3p0", 0x1.280000000001p0);
test("%a", "0x0.123p-1022", 0x0.123p-1022);
test("%1.3a", "0x1.230p-1026", 0x0.123p-1022);
test("%1.12a", "0x1.230000000000p-1026", 0x0.123p-1022);
test("%1.15a", "0x0.123000000000000p-1022", 0x0.123p-1022);
test("%1.5a", "0x1.00000p-1074", 0x0.0000000000001p-1022);
test("%1.7a", "0x1.0000000p-1022", 0x0.fffffffffffffp-1022);
test("%1.6a", "0x1.230000p-1026", 0x0.123000057p-1022);
test("%1.7a", "0x1.2300005p-1026", 0x0.123000057p-1022);
test("%1.8a", "0x1.23000057p-1026", 0x0.123000057p-1022);
test("%1.9a", "0x1.230000570p-1026", 0x0.123000057p-1022);
test("%1.6a", "0x1.230000p-1026", 0x0.123000058p-1022);
test("%1.7a", "0x1.2300006p-1026", 0x0.123000058p-1022);
test("%1.8a", "0x1.23000058p-1026", 0x0.123000058p-1022);
test("%1.9a", "0x1.230000580p-1026", 0x0.123000058p-1022);
test("%1.6a", "0x1.230000p-1026", 0x0.123000059p-1022);
test("%1.7a", "0x1.2300006p-1026", 0x0.123000059p-1022);
test("%1.8a", "0x1.23000059p-1026", 0x0.123000059p-1022);
test("%1.9a", "0x1.230000590p-1026", 0x0.123000059p-1022);
test("%1.4a", "0x1.0000p-1022", Math.nextDown(Double.MIN_NORMAL));
test("%a", "0x1.fffffffffffffp1023", Double.MAX_VALUE);
test("%1.1a", "0x1.0p1024", Double.MAX_VALUE);
test("%1.2a", "0x1.00p1024", Double.MAX_VALUE);
test("%1.6a", "0x1.000000p1024", Double.MAX_VALUE);
test("%1.9a", "0x1.000000000p1024", Double.MAX_VALUE);
test("%1.11a", "0x1.00000000000p1024", Double.MAX_VALUE);
test("%1.12a", "0x1.000000000000p1024", Double.MAX_VALUE);
test("%1.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE);
test("%.11a", "0x1.28000000000p0",
Double.parseDouble("0x1.280000000001p0"));
test("%.1a", "0x1.3p0", Double.parseDouble("0x1.280000000001p0"));
#end[double]
//---------------------------------------------------------------------

View File

@ -25,7 +25,7 @@
* @summary Unit test for formatter
* @bug 4906370 4962433 4973103 4989961 5005818 5031150 4970931 4989491 5002937
* 5005104 5007745 5061412 5055180 5066788 5088703 6317248 6318369 6320122
* 6344623 6369500 6534606 6282094 6286592 6476425 5063507 6469160
* 6344623 6369500 6534606 6282094 6286592 6476425 5063507 6469160 6476168
*
* @run shell/timeout=240 Basic.sh
*/

View File

@ -1319,10 +1319,8 @@ public class BasicDouble extends Basic {
Math.nextDown(DoubleConsts.MIN_NORMAL));
test("%.1a", "0x1.0p-1022",
Math.nextDown(DoubleConsts.MIN_NORMAL));
test("%.11a", "0x1.ffffffffffep-1023",
Double.parseDouble("0x0.fffffffffffp-1022"));
test("%.1a", "0x1.0p-1022",
Double.parseDouble("0x0.fffffffffffp-1022"));
test("%.11a", "0x1.ffffffffffep-1023", 0x0.fffffffffffp-1022);
test("%.1a", "0x1.0p-1022", 0x0.fffffffffffp-1022);
test("%.30a", "0x0.000000000000100000000000000000p-1022", Double.MIN_VALUE);
test("%.13a", "0x0.0000000000001p-1022", Double.MIN_VALUE);
test("%.11a", "0x1.00000000000p-1074", Double.MIN_VALUE);
@ -1336,19 +1334,50 @@ public class BasicDouble extends Basic {
test("%.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE);
test("%.11a", "0x1.00000000000p1024", Double.MAX_VALUE);
test("%.1a", "0x1.0p1024", Double.MAX_VALUE);
test("%.11a", "0x1.18000000000p0", Double.parseDouble("0x1.18p0"));
test("%.1a", "0x1.2p0", Double.parseDouble("0x1.18p0"));
test("%.11a", "0x1.18000000000p0", 0x1.18p0);
test("%.1a", "0x1.2p0", 0x1.18p0);
test("%.11a", "0x1.18000000000p0",
Double.parseDouble("0x1.180000000001p0"));
test("%.1a", "0x1.2p0",
Double.parseDouble("0x1.180000000001p0"));
test("%.11a", "0x1.28000000000p0", Double.parseDouble("0x1.28p0"));
test("%.1a", "0x1.2p0", Double.parseDouble("0x1.28p0"));
test("%.11a", "0x1.18000000000p0", 0x1.180000000001p0);
test("%.1a", "0x1.2p0", 0x1.180000000001p0);
test("%.11a", "0x1.28000000000p0", 0x1.28p0);
test("%.1a", "0x1.2p0", 0x1.28p0);
test("%.11a", "0x1.28000000000p0", 0x1.280000000001p0);
test("%.1a", "0x1.3p0", 0x1.280000000001p0);
test("%a", "0x0.123p-1022", 0x0.123p-1022);
test("%1.3a", "0x1.230p-1026", 0x0.123p-1022);
test("%1.12a", "0x1.230000000000p-1026", 0x0.123p-1022);
test("%1.15a", "0x0.123000000000000p-1022", 0x0.123p-1022);
test("%1.5a", "0x1.00000p-1074", 0x0.0000000000001p-1022);
test("%1.7a", "0x1.0000000p-1022", 0x0.fffffffffffffp-1022);
test("%1.6a", "0x1.230000p-1026", 0x0.123000057p-1022);
test("%1.7a", "0x1.2300005p-1026", 0x0.123000057p-1022);
test("%1.8a", "0x1.23000057p-1026", 0x0.123000057p-1022);
test("%1.9a", "0x1.230000570p-1026", 0x0.123000057p-1022);
test("%1.6a", "0x1.230000p-1026", 0x0.123000058p-1022);
test("%1.7a", "0x1.2300006p-1026", 0x0.123000058p-1022);
test("%1.8a", "0x1.23000058p-1026", 0x0.123000058p-1022);
test("%1.9a", "0x1.230000580p-1026", 0x0.123000058p-1022);
test("%1.6a", "0x1.230000p-1026", 0x0.123000059p-1022);
test("%1.7a", "0x1.2300006p-1026", 0x0.123000059p-1022);
test("%1.8a", "0x1.23000059p-1026", 0x0.123000059p-1022);
test("%1.9a", "0x1.230000590p-1026", 0x0.123000059p-1022);
test("%1.4a", "0x1.0000p-1022", Math.nextDown(Double.MIN_NORMAL));
test("%a", "0x1.fffffffffffffp1023", Double.MAX_VALUE);
test("%1.1a", "0x1.0p1024", Double.MAX_VALUE);
test("%1.2a", "0x1.00p1024", Double.MAX_VALUE);
test("%1.6a", "0x1.000000p1024", Double.MAX_VALUE);
test("%1.9a", "0x1.000000000p1024", Double.MAX_VALUE);
test("%1.11a", "0x1.00000000000p1024", Double.MAX_VALUE);
test("%1.12a", "0x1.000000000000p1024", Double.MAX_VALUE);
test("%1.13a", "0x1.fffffffffffffp1023", Double.MAX_VALUE);
test("%.11a", "0x1.28000000000p0",
Double.parseDouble("0x1.280000000001p0"));
test("%.1a", "0x1.3p0", Double.parseDouble("0x1.280000000001p0"));
//---------------------------------------------------------------------