ParserHelper { public float parseFloat() { int mant = 0; int mantDig = 0; boolean mantPos = true; boolean mantRead = false; int exp = 0; int expDig = 0; int expAdj = 0; boolean expPos = true; switch (current) { case '-': mantPos = false; case '+': current = read(); } m1: switch (current) { default: return Float.NaN; case '.': break; case '0': mantRead = true; l: for (;;) { current = read(); switch (current) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': break l; case '.': case 'e': case 'E': break m1; default: return 0.0f; case '0': } } case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': mantRead = true; l: for (;;) { if (mantDig < 9) { mantDig++; mant = mant * 10 + (current - '0'); } else { expAdj++; } current = read(); switch (current) { default: break l; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': } } } if (current == '.') { current = read(); m2: switch (current) { default: case 'e': case 'E': if (!mantRead) { reportUnexpectedCharacterError( current ); } break; case '0': if (mantDig == 0) { l: for (;;) { current = read(); expAdj--; switch (current) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': break l; default: if (!mantRead) { return 0.0f; } break m2; case '0': } } } case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': l: for (;;) { if (mantDig < 9) { mantDig++; mant = mant * 10 + (current - '0'); expAdj--; } current = read(); switch (current) { default: break l; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': } } } } switch (current) { case 'e': case 'E': current = read(); switch (current) { default: reportUnexpectedCharacterError( current ); case '-': expPos = false; case '+': current = read(); switch (current) { default: reportUnexpectedCharacterError( current ); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': } en: switch (current) { case '0': l: for (;;) { current = read(); switch (current) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': break l; default: break en; case '0': } } case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': l: for (;;) { if (expDig < 3) { expDig++; exp = exp * 10 + (current - '0'); } current = read(); switch (current) { default: break l; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': } } } default: } if (!expPos) { exp = -exp; } exp += expAdj; if (!mantPos) { mant = -mant; } return buildFloat(mant, exp); } ParserHelper(CharSequence s, int pos); void skipWhitespace(); void skipNumberSeparator(); void advance(); float parseFloat(); static float buildFloat(int mant, int exp); float nextFloat(); public int pos; }
@Test public void testParseFloat() { assertThat(new ParserHelper("0", 0).parseFloat(), is(0.0f)); assertThat(new ParserHelper("0.09", 0).parseFloat(), is(0.09F)); assertThat(new ParserHelper("0.0e3", 0).parseFloat(), is(0.0F)); assertThat(new ParserHelper("0.01", 0).parseFloat(), is(0.01F)); assertThat(new ParserHelper("foo", 0).parseFloat(), is(Float.NaN)); }