ParseHexFloatingPoint.java revision 2362
2362N/A * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. 2362N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 0N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A * or visit www.oracle.com if you need additional information or have any 0N/A * @summary Numerical tests for hexadecimal inputs to parseDouble, parseFloat 0N/A * @author Joseph D. Darcy // Try different combination of letter components for(
int i =
0; i <
2; i++) {
for(
int j =
0; j <
2; j++) {
for(
int k =
0; k <
2; k++) {
* Test easy and tricky double rounding cases. // Hex strings that convert to three; test basic functionality // of significand and exponent shift adjusts along with the // no-op of adding leading zeros. These cases don't exercise // Test zero significand with large exponents. // Test nonzero significand with large exponents. // Test significands with different lengths and bit patterns. for(
int i =
1; i <=
0xe; i++) {
new PairSD(
"0x0.0p0",
0.0/
16.0),
new PairSD(
"0x0.1p0",
1.0/
16.0),
new PairSD(
"0x0.2p0",
2.0/
16.0),
new PairSD(
"0x0.3p0",
3.0/
16.0),
new PairSD(
"0x0.4p0",
4.0/
16.0),
new PairSD(
"0x0.5p0",
5.0/
16.0),
new PairSD(
"0x0.6p0",
6.0/
16.0),
new PairSD(
"0x0.7p0",
7.0/
16.0),
new PairSD(
"0x0.8p0",
8.0/
16.0),
new PairSD(
"0x0.9p0",
9.0/
16.0),
new PairSD(
"0x0.ap0",
10.0/
16.0),
new PairSD(
"0x0.bp0",
11.0/
16.0),
new PairSD(
"0x0.cp0",
12.0/
16.0),
new PairSD(
"0x0.dp0",
13.0/
16.0),
new PairSD(
"0x0.ep0",
14.0/
16.0),
new PairSD(
"0x0.fp0",
15.0/
16.0),
// Half-way case between zero and MIN_VALUE rounds down to new PairSD(
"0x1.0p-1075",
0.0),
// Slighly more than half-way case between zero and // MIN_VALUES rounds up to zero. // More subnormal rounding tests // Large value and overflow rounding tests // Consistency check; double => hexadecimal => double // preserves the original value. for(
int i =
0; i <
1000; i++) {
* Verify rounding works the same regardless of how the * significand is aligned on input. A useful extension could be * to have this sort of test for strings near the overflow // baseSignif * 2^baseExp = nextDown(2.0) for(
int i =
0; i <
2; i++) {
for(
long j =
0; j <=
0xfL; j++) {
for(
long k =
0; k <=
8; k+=
4) {
// k = {0, 4, 8} // Calculate when significand should be incremented // see table 4.7 in Koren book if ((
base &
0x100L) ==
0L ) {
// lsb is 0 if ( (j >=
8L) &&
// round is 1 ((j &
0x7L) !=
0 || k !=
0 ) )
// sticky is 1 if (j >=
8L)
// round is 1 for(
int m = -
2; m <=
3; m++) {
// Form equal value string and evaluate it * Test tricky float rounding cases. The code which * reads in a hex string converts the string to a double value. * If a float value is needed, the double value is cast to float. * However, the cast be itself not always guaranteed to return the * 1. hex string => double can discard a sticky bit which would * influence a direct hex string => float conversion. * 2. hex string => double => float can have a rounding to double * precision which results in a larger float value while a direct * hex string => float conversion would not round up. * This method includes tests of the latter two possibilities. // Target float value hard rouding version {
"0x1.000000p0",
"0x1.0000000000001p0"},
// Try some values that should round up to nextUp(1.0f) {
"0x1.000002p0",
"0x1.0000010000001p0"},
{
"0x1.000002p0",
"0x1.00000100000008p0"},
{
"0x1.000002p0",
"0x1.0000010000000fp0"},
{
"0x1.000002p0",
"0x1.00000100000001p0"},
{
"0x1.000002p0",
"0x1.00000100000000000000000000000000000000001p0"},
{
"0x1.000002p0",
"0x1.0000010000000fp0"},
// Potential double rounding cases {
"0x1.000002p0",
"0x1.000002fffffffp0"},
{
"0x1.000002p0",
"0x1.000002fffffff8p0"},
{
"0x1.000002p0",
"0x1.000002ffffffffp0"},
{
"0x1.000002p0",
"0x1.000002ffff0ffp0"},
{
"0x1.000002p0",
"0x1.000002ffff0ff8p0"},
{
"0x1.000002p0",
"0x1.000002ffff0fffp0"},
{
"0x1.000000p0",
"0x1.000000fffffffp0"},
{
"0x1.000000p0",
"0x1.000000fffffff8p0"},
{
"0x1.000000p0",
"0x1.000000ffffffffp0"},
{
"0x1.000000p0",
"0x1.000000ffffffep0"},
{
"0x1.000000p0",
"0x1.000000ffffffe8p0"},
{
"0x1.000000p0",
"0x1.000000ffffffefp0"},
{
"0x0.000002p-126",
"0x0.0000010000001p-126"},
{
"0x0.000002p-126",
"0x0.00000100000000000001p-126"},
{
"0x0.000006p-126",
"0x0.0000050000001p-126"},
{
"0x0.000006p-126",
"0x0.00000500000000000001p-126"},
{
"0x0.0p-149",
"0x0.7ffffffffffffffp-149"},
{
"0x1.0p-148",
"0x1.3ffffffffffffffp-148"},
{
"0x1.cp-147",
"0x1.bffffffffffffffp-147"},
{
"0x1.fffffcp-127",
"0x1.fffffdffffffffp-127"},
"testing hexadecimal floating-point " +