src/java.base/share/classes/java/lang/Long.java

Print this page
rev 10594 : 8055251: Re-examine Integer.parseInt and Long.parseLong methods

*** 604,655 **** } } /** * Parses the {@link CharSequence} argument as a signed {@code long} in - * the specified {@code radix}, beginning at the specified {@code beginIndex} - * and extending to the end of the sequence. - * - * <p>The method does not take steps to guard against the - * {@code CharSequence} being mutated while parsing. - * - * @param s the {@code CharSequence} containing the {@code long} - * representation to be parsed - * @param radix the radix to be used while parsing {@code s}. - * @param beginIndex the beginning index, inclusive. - * @return the signed {@code long} represented by the subsequence in - * the specified radix. - * @throws NullPointerException if {@code s} is null. - * @throws IndexOutOfBoundsException if {@code beginIndex} is - * negative, or if {@code beginIndex} is greater than - * {@code s.length()}. - * @throws NumberFormatException if the {@code CharSequence} does not - * contain a parsable {@code long} in the specified - * {@code radix}, or if {@code radix} is either smaller than - * {@link java.lang.Character#MIN_RADIX} or larger than - * {@link java.lang.Character#MAX_RADIX}. - * @since 1.9 - */ - public static long parseLong(CharSequence s, int radix, int beginIndex) - throws NumberFormatException { - // forces a null check of s - return parseLong(s, radix, beginIndex, s.length()); - } - - /** - * Parses the {@link CharSequence} argument as a signed {@code long} in * the specified {@code radix}, beginning at the specified * {@code beginIndex} and extending to {@code endIndex - 1}. * * <p>The method does not take steps to guard against the * {@code CharSequence} being mutated while parsing. * * @param s the {@code CharSequence} containing the {@code long} * representation to be parsed - * @param radix the radix to be used while parsing {@code s}. * @param beginIndex the beginning index, inclusive. * @param endIndex the ending index, exclusive. * @return the signed {@code long} represented by the subsequence in * the specified radix. * @throws NullPointerException if {@code s} is null. * @throws IndexOutOfBoundsException if {@code beginIndex} is * negative, or if {@code beginIndex} is greater than --- 604,624 ---- } } /** * Parses the {@link CharSequence} argument as a signed {@code long} in * the specified {@code radix}, beginning at the specified * {@code beginIndex} and extending to {@code endIndex - 1}. * * <p>The method does not take steps to guard against the * {@code CharSequence} being mutated while parsing. * * @param s the {@code CharSequence} containing the {@code long} * representation to be parsed * @param beginIndex the beginning index, inclusive. * @param endIndex the ending index, exclusive. + * @param radix the radix to be used while parsing {@code s}. * @return the signed {@code long} represented by the subsequence in * the specified radix. * @throws NullPointerException if {@code s} is null. * @throws IndexOutOfBoundsException if {@code beginIndex} is * negative, or if {@code beginIndex} is greater than
*** 660,670 **** * {@code radix}, or if {@code radix} is either smaller than * {@link java.lang.Character#MIN_RADIX} or larger than * {@link java.lang.Character#MAX_RADIX}. * @since 1.9 */ ! public static long parseLong(CharSequence s, int radix, int beginIndex, int endIndex) throws NumberFormatException { s = Objects.requireNonNull(s); if (beginIndex < 0 || beginIndex > endIndex || endIndex > s.length()) { throw new IndexOutOfBoundsException(); --- 629,639 ---- * {@code radix}, or if {@code radix} is either smaller than * {@link java.lang.Character#MIN_RADIX} or larger than * {@link java.lang.Character#MAX_RADIX}. * @since 1.9 */ ! public static long parseLong(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException { s = Objects.requireNonNull(s); if (beginIndex < 0 || beginIndex > endIndex || endIndex > s.length()) { throw new IndexOutOfBoundsException();
*** 700,719 **** } long multmin = limit / radix; long result = 0; while (i < endIndex) { // Accumulating negatively avoids surprises near MAX_VALUE ! int digit = Character.digit(s.charAt(i++), radix); if (digit < 0 || result < multmin) { throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i); } result *= radix; if (result < limit + digit) { throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i); } result -= digit; } return negative ? result : -result; } else { throw new NumberFormatException(""); --- 669,689 ---- } long multmin = limit / radix; long result = 0; while (i < endIndex) { // Accumulating negatively avoids surprises near MAX_VALUE ! int digit = Character.digit(s.charAt(i), radix); if (digit < 0 || result < multmin) { throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i); } result *= radix; if (result < limit + digit) { throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i); } + i++; result -= digit; } return negative ? result : -result; } else { throw new NumberFormatException("");
*** 809,819 **** (radix == 10 && len <= 18) ) { // Long.MAX_VALUE in base 10 is 19 digits return parseLong(s, radix); } // No need for range checks on len due to testing above. ! long first = parseLong(s, radix, 0, len - 1); int second = Character.digit(s.charAt(len - 1), radix); if (second < 0) { throw new NumberFormatException("Bad digit at end of " + s); } long result = first * radix + second; --- 779,789 ---- (radix == 10 && len <= 18) ) { // Long.MAX_VALUE in base 10 is 19 digits return parseLong(s, radix); } // No need for range checks on len due to testing above. ! long first = parseLong(s, 0, len - 1, radix); int second = Character.digit(s.charAt(len - 1), radix); if (second < 0) { throw new NumberFormatException("Bad digit at end of " + s); } long result = first * radix + second;
*** 881,931 **** } /** * Parses the {@link CharSequence} argument as an unsigned {@code long} in * the specified {@code radix}, beginning at the specified - * {@code beginIndex} and extending to the end of the sequence. - * - * <p>The method does not take steps to guard against the - * {@code CharSequence} being mutated while parsing. - * - * @param s the {@code CharSequence} containing the unsigned - * {@code long} representation to be parsed - * @param radix the radix to be used while parsing {@code s}. - * @param beginIndex the beginning index, inclusive. - * @return the unsigned {@code long} represented by the subsequence in - * the specified radix. - * @throws NullPointerException if {@code s} is null. - * @throws IndexOutOfBoundsException if {@code beginIndex} is - * negative, or if {@code beginIndex} is greater than - * {@code s.length()}. - * @throws NumberFormatException if the {@code CharSequence} does not - * contain a parsable unsigned {@code long} in the specified - * {@code radix}, or if {@code radix} is either smaller than - * {@link java.lang.Character#MIN_RADIX} or larger than - * {@link java.lang.Character#MAX_RADIX}. - * @since 1.9 - */ - public static long parseUnsignedLong(CharSequence s, int radix, int beginIndex) - throws NumberFormatException { - // forces a null check of s - return parseUnsignedLong(s, radix, beginIndex, s.length()); - } - - /** - * Parses the {@link CharSequence} argument as an unsigned {@code long} in - * the specified {@code radix}, beginning at the specified * {@code beginIndex} and extending to {@code endIndex - 1}. * * <p>The method does not take steps to guard against the * {@code CharSequence} being mutated while parsing. * * @param s the {@code CharSequence} containing the unsigned * {@code long} representation to be parsed - * @param radix the radix to be used while parsing {@code s}. * @param beginIndex the beginning index, inclusive. * @param endIndex the ending index, exclusive. * @return the unsigned {@code long} represented by the subsequence in * the specified radix. * @throws NullPointerException if {@code s} is null. * @throws IndexOutOfBoundsException if {@code beginIndex} is * negative, or if {@code beginIndex} is greater than --- 851,870 ---- } /** * Parses the {@link CharSequence} argument as an unsigned {@code long} in * the specified {@code radix}, beginning at the specified * {@code beginIndex} and extending to {@code endIndex - 1}. * * <p>The method does not take steps to guard against the * {@code CharSequence} being mutated while parsing. * * @param s the {@code CharSequence} containing the unsigned * {@code long} representation to be parsed * @param beginIndex the beginning index, inclusive. * @param endIndex the ending index, exclusive. + * @param radix the radix to be used while parsing {@code s}. * @return the unsigned {@code long} represented by the subsequence in * the specified radix. * @throws NullPointerException if {@code s} is null. * @throws IndexOutOfBoundsException if {@code beginIndex} is * negative, or if {@code beginIndex} is greater than
*** 936,946 **** * {@code radix}, or if {@code radix} is either smaller than * {@link java.lang.Character#MIN_RADIX} or larger than * {@link java.lang.Character#MAX_RADIX}. * @since 1.9 */ ! public static long parseUnsignedLong(CharSequence s, int radix, int beginIndex, int endIndex) throws NumberFormatException { s = Objects.requireNonNull(s); if (beginIndex < 0 || beginIndex > endIndex || endIndex > s.length()) { throw new IndexOutOfBoundsException(); --- 875,885 ---- * {@code radix}, or if {@code radix} is either smaller than * {@link java.lang.Character#MIN_RADIX} or larger than * {@link java.lang.Character#MAX_RADIX}. * @since 1.9 */ ! public static long parseUnsignedLong(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException { s = Objects.requireNonNull(s); if (beginIndex < 0 || beginIndex > endIndex || endIndex > s.length()) { throw new IndexOutOfBoundsException();
*** 953,967 **** throw new NumberFormatException(String.format("Illegal leading minus sign " + "on unsigned string %s.", s.subSequence(start, start + len))); } else { if (len <= 12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits (radix == 10 && len <= 18) ) { // Long.MAX_VALUE in base 10 is 19 digits ! return parseLong(s, radix, start, start + len); } // No need for range checks on end due to testing above. ! long first = parseLong(s, radix, start, start + len - 1); int second = Character.digit(s.charAt(start + len - 1), radix); if (second < 0) { throw new NumberFormatException("Bad digit at end of " + s.subSequence(start, start + len)); } --- 892,906 ---- throw new NumberFormatException(String.format("Illegal leading minus sign " + "on unsigned string %s.", s.subSequence(start, start + len))); } else { if (len <= 12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits (radix == 10 && len <= 18) ) { // Long.MAX_VALUE in base 10 is 19 digits ! return parseLong(s, start, start + len, radix); } // No need for range checks on end due to testing above. ! long first = parseLong(s, start, start + len - 1, radix); int second = Character.digit(s.charAt(start + len - 1), radix); if (second < 0) { throw new NumberFormatException("Bad digit at end of " + s.subSequence(start, start + len)); }