Path: blob/master/test/jdk/java/lang/Float/ParseFloat.java
41149 views
/*1* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 4160406 4705734 4707389 6358355 703215426* @summary Tests for Float.parseFloat method27*/2829import java.math.BigDecimal;30import java.math.BigInteger;3132public class ParseFloat {3334private static final BigDecimal HALF = BigDecimal.valueOf(0.5);3536private static void fail(String val, float n) {37throw new RuntimeException("Float.parseFloat failed. String:" +38val + " Result:" + n);39}4041private static void check(String val) {42float n = Float.parseFloat(val);43boolean isNegativeN = n < 0 || n == 0 && 1/n < 0;44float na = Math.abs(n);45String s = val.trim().toLowerCase();46switch (s.charAt(s.length() - 1)) {47case 'd':48case 'f':49s = s.substring(0, s.length() - 1);50break;51}52boolean isNegative = false;53if (s.charAt(0) == '+') {54s = s.substring(1);55} else if (s.charAt(0) == '-') {56s = s.substring(1);57isNegative = true;58}59if (s.equals("nan")) {60if (!Float.isNaN(n)) {61fail(val, n);62}63return;64}65if (Float.isNaN(n)) {66fail(val, n);67}68if (isNegativeN != isNegative)69fail(val, n);70if (s.equals("infinity")) {71if (na != Float.POSITIVE_INFINITY) {72fail(val, n);73}74return;75}76BigDecimal bd;77if (s.startsWith("0x")) {78s = s.substring(2);79int indP = s.indexOf('p');80long exp = Long.parseLong(s.substring(indP + 1));81int indD = s.indexOf('.');82String significand;83if (indD >= 0) {84significand = s.substring(0, indD) + s.substring(indD + 1, indP);85exp -= 4*(indP - indD - 1);86} else {87significand = s.substring(0, indP);88}89bd = new BigDecimal(new BigInteger(significand, 16));90if (exp >= 0) {91bd = bd.multiply(BigDecimal.valueOf(2).pow((int)exp));92} else {93bd = bd.divide(BigDecimal.valueOf(2).pow((int)-exp));94}95} else {96bd = new BigDecimal(s);97}98BigDecimal l, u;99if (Float.isInfinite(na)) {100l = new BigDecimal(Float.MAX_VALUE).add(new BigDecimal(Math.ulp(Float.MAX_VALUE)).multiply(HALF));101u = null;102} else {103l = new BigDecimal(na).subtract(new BigDecimal(Math.ulp(-Math.nextUp(-na))).multiply(HALF));104u = new BigDecimal(na).add(new BigDecimal(Math.ulp(n)).multiply(HALF));105}106int cmpL = bd.compareTo(l);107int cmpU = u != null ? bd.compareTo(u) : -1;108if ((Float.floatToIntBits(n) & 1) != 0) {109if (cmpL <= 0 || cmpU >= 0) {110fail(val, n);111}112} else {113if (cmpL < 0 || cmpU > 0) {114fail(val, n);115}116}117}118119private static void check(String val, float expected) {120float n = Float.parseFloat(val);121if (n != expected)122fail(val, n);123check(val);124}125126private static void rudimentaryTest() {127check(new String(""+Float.MIN_VALUE), Float.MIN_VALUE);128check(new String(""+Float.MAX_VALUE), Float.MAX_VALUE);129130check("10", (float) 10.0);131check("10.0", (float) 10.0);132check("10.01", (float) 10.01);133134check("-10", (float) -10.0);135check("-10.00", (float) -10.0);136check("-10.01", (float) -10.01);137138// bug 6358355139check("144115196665790480", 0x1.000002p57f);140check("144115196665790481", 0x1.000002p57f);141check("0.050000002607703203", 0.05f);142check("0.050000002607703204", 0.05f);143check("0.050000002607703205", 0.05f);144check("0.050000002607703206", 0.05f);145check("0.050000002607703207", 0.05f);146check("0.050000002607703208", 0.05f);147check("0.050000002607703209", 0.050000004f);148}149150static String badStrings[] = {151"",152"+",153"-",154"+e",155"-e",156"+e170",157"-e170",158159// Make sure intermediate white space is not deleted.160"1234 e10",161"-1234 e10",162163// Control characters in the interior of a string are not legal164"1\u0007e1",165"1e\u00071",166167// NaN and infinity can't have trailing type suffices or exponents168"NaNf",169"NaNF",170"NaNd",171"NaND",172"-NaNf",173"-NaNF",174"-NaNd",175"-NaND",176"+NaNf",177"+NaNF",178"+NaNd",179"+NaND",180"Infinityf",181"InfinityF",182"Infinityd",183"InfinityD",184"-Infinityf",185"-InfinityF",186"-Infinityd",187"-InfinityD",188"+Infinityf",189"+InfinityF",190"+Infinityd",191"+InfinityD",192193"NaNe10",194"-NaNe10",195"+NaNe10",196"Infinitye10",197"-Infinitye10",198"+Infinitye10",199200// Non-ASCII digits are not recognized201"\u0661e\u0661", // 1e1 in Arabic-Indic digits202"\u06F1e\u06F1", // 1e1 in Extended Arabic-Indic digits203"\u0967e\u0967" // 1e1 in Devanagari digits204};205206static String goodStrings[] = {207"NaN",208"+NaN",209"-NaN",210"Infinity",211"+Infinity",212"-Infinity",213"1.1e-23f",214".1e-23f",215"1e-23",216"1f",217"1",218"2",219"1234",220"-1234",221"+1234",222"2147483647", // Integer.MAX_VALUE223"2147483648",224"-2147483648", // Integer.MIN_VALUE225"-2147483649",226227"16777215",228"16777216", // 2^24229"16777217",230231"-16777215",232"-16777216", // -2^24233"-16777217",234235"9007199254740991",236"9007199254740992", // 2^53237"9007199254740993",238239"-9007199254740991",240"-9007199254740992", // -2^53241"-9007199254740993",242243"9223372036854775807",244"9223372036854775808", // Long.MAX_VALUE245"9223372036854775809",246247"-9223372036854775808",248"-9223372036854775809", // Long.MIN_VALUE249"-9223372036854775810"250};251252static String paddedBadStrings[];253static String paddedGoodStrings[];254static {255String pad = " \t\n\r\f\u0001\u000b\u001f";256paddedBadStrings = new String[badStrings.length];257for(int i = 0 ; i < badStrings.length; i++)258paddedBadStrings[i] = pad + badStrings[i] + pad;259260paddedGoodStrings = new String[goodStrings.length];261for(int i = 0 ; i < goodStrings.length; i++)262paddedGoodStrings[i] = pad + goodStrings[i] + pad;263264}265266/*267* Throws an exception if <code>Input</code> is268* <code>exceptionalInput</code> and {@link Float.parseFloat269* parseFloat} does <em>not</em> throw an exception or if270* <code>Input</code> is not <code>exceptionalInput</code> and271* <code>parseFloat</code> throws an exception. This method does272* not attempt to test whether the string is converted to the273* proper value; just whether the input is accepted appropriately274* or not.275*/276private static void testParsing(String [] input,277boolean exceptionalInput) {278for(int i = 0; i < input.length; i++) {279double d;280281try {282d = Float.parseFloat(input[i]);283check(input[i]);284}285catch (NumberFormatException e) {286if (! exceptionalInput) {287throw new RuntimeException("Float.parseFloat rejected " +288"good string `" + input[i] +289"'.");290}291break;292}293if (exceptionalInput) {294throw new RuntimeException("Float.parseFloat accepted " +295"bad string `" + input[i] +296"'.");297}298}299}300301/**302* For each power of two, test at boundaries of303* region that should convert to that value.304*/305private static void testPowers() {306for(int i = -149; i <= +127; i++) {307float f = Math.scalb(1.0f, i);308BigDecimal f_BD = new BigDecimal(f);309310BigDecimal lowerBound = f_BD.subtract(new BigDecimal(Math.ulp(-Math.nextUp(-f))).multiply(HALF));311BigDecimal upperBound = f_BD.add(new BigDecimal(Math.ulp(f)).multiply(HALF));312313check(lowerBound.toString());314check(upperBound.toString());315}316check(new BigDecimal(Float.MAX_VALUE).add(new BigDecimal(Math.ulp(Float.MAX_VALUE)).multiply(HALF)).toString());317}318319public static void main(String[] args) throws Exception {320rudimentaryTest();321322testParsing(goodStrings, false);323testParsing(paddedGoodStrings, false);324testParsing(badStrings, true);325testParsing(paddedBadStrings, true);326327testPowers();328}329}330331332