1 /*
   2  * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 4160406 4705734 4707389
  27  * @summary Tests for Float.parseFloat method
  28  */
  29 
  30 public class ParseFloat {
  31 
  32     private static void check(String val, float expected) {
  33         float n = Float.parseFloat(val);
  34         if (n != expected)
  35             throw new RuntimeException("Float.parseFloat failed. String:" +
  36                                                 val + " Result:" + n);
  37     }
  38 
  39     private static void rudimentaryTest() {
  40         check(new String(""+Float.MIN_VALUE), Float.MIN_VALUE);
  41         check(new String(""+Float.MAX_VALUE), Float.MAX_VALUE);
  42 
  43         check("10",     (float)  10.0);
  44         check("10.0",   (float)  10.0);
  45         check("10.01",  (float)  10.01);
  46 
  47         check("-10",    (float) -10.0);
  48         check("-10.00", (float) -10.0);
  49         check("-10.01", (float) -10.01);
  50     }
  51 
  52     static  String badStrings[] = {
  53         "",
  54         "+",
  55         "-",
  56         "+e",
  57         "-e",
  58         "+e170",
  59         "-e170",
  60 
  61         // Make sure intermediate white space is not deleted.
  62         "1234   e10",
  63         "-1234   e10",
  64 
  65         // Control characters in the interior of a string are not legal
  66         "1\u0007e1",
  67         "1e\u00071",
  68 
  69         // NaN and infinity can't have trailing type suffices or exponents
  70         "NaNf",
  71         "NaNF",
  72         "NaNd",
  73         "NaND",
  74         "-NaNf",
  75         "-NaNF",
  76         "-NaNd",
  77         "-NaND",
  78         "+NaNf",
  79         "+NaNF",
  80         "+NaNd",
  81         "+NaND",
  82         "Infinityf",
  83         "InfinityF",
  84         "Infinityd",
  85         "InfinityD",
  86         "-Infinityf",
  87         "-InfinityF",
  88         "-Infinityd",
  89         "-InfinityD",
  90         "+Infinityf",
  91         "+InfinityF",
  92         "+Infinityd",
  93         "+InfinityD",
  94 
  95         "NaNe10",
  96         "-NaNe10",
  97         "+NaNe10",
  98         "Infinitye10",
  99         "-Infinitye10",
 100         "+Infinitye10",
 101 
 102         // Non-ASCII digits are not recognized
 103         "\u0661e\u0661", // 1e1 in Arabic-Indic digits
 104         "\u06F1e\u06F1", // 1e1 in Extended Arabic-Indic digits
 105         "\u0967e\u0967" // 1e1 in Devanagari digits
 106     };
 107 
 108     static String goodStrings[] = {
 109         "NaN",
 110         "+NaN",
 111         "-NaN",
 112         "Infinity",
 113         "+Infinity",
 114         "-Infinity",
 115         "1.1e-23f",
 116         ".1e-23f",
 117         "1e-23",
 118         "1f",
 119         "1",
 120         "2",
 121         "1234",
 122         "-1234",
 123         "+1234",
 124         "2147483647",   // Integer.MAX_VALUE
 125         "2147483648",
 126         "-2147483648",  // Integer.MIN_VALUE
 127         "-2147483649",
 128 
 129         "16777215",
 130         "16777216",     // 2^24
 131         "16777217",
 132 
 133         "-16777215",
 134         "-16777216",    // -2^24
 135         "-16777217",
 136 
 137         "9007199254740991",
 138         "9007199254740992",     // 2^53
 139         "9007199254740993",
 140 
 141         "-9007199254740991",
 142         "-9007199254740992",    // -2^53
 143         "-9007199254740993",
 144 
 145         "9223372036854775807",
 146         "9223372036854775808",  // Long.MAX_VALUE
 147         "9223372036854775809",
 148 
 149         "-9223372036854775808",
 150         "-9223372036854775809", // Long.MIN_VALUE
 151         "-9223372036854775810"
 152     };
 153 
 154     static String paddedBadStrings[];
 155     static String paddedGoodStrings[];
 156     static {
 157         String pad = " \t\n\r\f\u0001\u000b\u001f";
 158         paddedBadStrings = new String[badStrings.length];
 159         for(int i = 0 ; i <  badStrings.length; i++)
 160             paddedBadStrings[i] = pad + badStrings[i] + pad;
 161 
 162         paddedGoodStrings = new String[goodStrings.length];
 163         for(int i = 0 ; i <  goodStrings.length; i++)
 164             paddedGoodStrings[i] = pad + goodStrings[i] + pad;
 165 
 166     }
 167 
 168     /*
 169      * Throws an exception if <code>Input</code> is
 170      * <code>exceptionalInput</code> and {@link Float.parseFloat
 171      * parseFloat} does <em>not</em> throw an exception or if
 172      * <code>Input</code> is not <code>exceptionalInput</code> and
 173      * <code>parseFloat</code> throws an exception.  This method does
 174      * not attempt to test whether the string is converted to the
 175      * proper value; just whether the input is accepted appropriately
 176      * or not.
 177      */
 178     private static void testParsing(String [] input,
 179                                     boolean exceptionalInput) {
 180         for(int i = 0; i < input.length; i++) {
 181             double d;
 182 
 183             try {
 184                 d = Float.parseFloat(input[i]);
 185             }
 186             catch (NumberFormatException e) {
 187                 if (! exceptionalInput) {
 188                     throw new RuntimeException("Float.parseFloat rejected " +
 189                                                "good string `" + input[i] +
 190                                                "'.");
 191                 }
 192                 break;
 193             }
 194             if (exceptionalInput) {
 195                 throw new RuntimeException("Float.parseFloat accepted " +
 196                                            "bad string `" + input[i] +
 197                                            "'.");
 198             }
 199         }
 200     }
 201 
 202     public static void main(String[] args) throws Exception {
 203         rudimentaryTest();
 204 
 205         testParsing(goodStrings, false);
 206         testParsing(paddedGoodStrings, false);
 207         testParsing(badStrings, true);
 208         testParsing(paddedBadStrings, true);
 209     }
 210 }