658 if (radix < Character.MIN_RADIX) {
659 throw new NumberFormatException("radix " + radix +
660 " less than Character.MIN_RADIX");
661 }
662 if (radix > Character.MAX_RADIX) {
663 throw new NumberFormatException("radix " + radix +
664 " greater than Character.MAX_RADIX");
665 }
666
667 boolean negative = false;
668 int i = 0, len = s.length();
669 long limit = -Long.MAX_VALUE;
670
671 if (len > 0) {
672 char firstChar = s.charAt(0);
673 if (firstChar < '0') { // Possible leading "+" or "-"
674 if (firstChar == '-') {
675 negative = true;
676 limit = Long.MIN_VALUE;
677 } else if (firstChar != '+') {
678 throw NumberFormatException.forInputString(s);
679 }
680
681 if (len == 1) { // Cannot have lone "+" or "-"
682 throw NumberFormatException.forInputString(s);
683 }
684 i++;
685 }
686 long multmin = limit / radix;
687 long result = 0;
688 while (i < len) {
689 // Accumulating negatively avoids surprises near MAX_VALUE
690 int digit = Character.digit(s.charAt(i++),radix);
691 if (digit < 0 || result < multmin) {
692 throw NumberFormatException.forInputString(s);
693 }
694 result *= radix;
695 if (result < limit + digit) {
696 throw NumberFormatException.forInputString(s);
697 }
698 result -= digit;
699 }
700 return negative ? result : -result;
701 } else {
702 throw NumberFormatException.forInputString(s);
703 }
704 }
705
706 /**
707 * Parses the {@link CharSequence} argument as a signed {@code long} in
708 * the specified {@code radix}, beginning at the specified
709 * {@code beginIndex} and extending to {@code endIndex - 1}.
710 *
711 * <p>The method does not take steps to guard against the
712 * {@code CharSequence} being mutated while parsing.
713 *
714 * @param s the {@code CharSequence} containing the {@code long}
715 * representation to be parsed
716 * @param beginIndex the beginning index, inclusive.
717 * @param endIndex the ending index, exclusive.
718 * @param radix the radix to be used while parsing {@code s}.
719 * @return the signed {@code long} represented by the subsequence in
720 * the specified radix.
721 * @throws NullPointerException if {@code s} is null.
722 * @throws IndexOutOfBoundsException if {@code beginIndex} is
928 * radix*first + second <= (radix*left7) * 2^57 + radix*(2^57 - 1) + 36
929 * thus
930 * radix*first + second < 128 * 2^57 + 36*2^57 - radix + 36
931 * whence
932 * radix*first + second < 2^64 + 2^6*2^57 = 2^64 + 2^63
933 *
934 * E) Conditions C, D, and result >= 0:
935 * C and D combined imply the mathematical result
936 * 2^63 < first*radix + second < 2^64 + 2^63. The lower
937 * bound is therefore negative as a signed long, but the
938 * upper bound is too small to overflow again after the
939 * signed long overflows to positive above 2^64 - 1. Hence
940 * result >= 0 implies overflow given C and D.
941 */
942 throw new NumberFormatException(String.format("String value %s exceeds " +
943 "range of unsigned long.", s));
944 }
945 return result;
946 }
947 } else {
948 throw NumberFormatException.forInputString(s);
949 }
950 }
951
952 /**
953 * Parses the {@link CharSequence} argument as an unsigned {@code long} in
954 * the specified {@code radix}, beginning at the specified
955 * {@code beginIndex} and extending to {@code endIndex - 1}.
956 *
957 * <p>The method does not take steps to guard against the
958 * {@code CharSequence} being mutated while parsing.
959 *
960 * @param s the {@code CharSequence} containing the unsigned
961 * {@code long} representation to be parsed
962 * @param beginIndex the beginning index, inclusive.
963 * @param endIndex the ending index, exclusive.
964 * @param radix the radix to be used while parsing {@code s}.
965 * @return the unsigned {@code long} represented by the subsequence in
966 * the specified radix.
967 * @throws NullPointerException if {@code s} is null.
968 * @throws IndexOutOfBoundsException if {@code beginIndex} is
1046 * radix*first + second <= (radix*left7) * 2^57 + radix*(2^57 - 1) + 36
1047 * thus
1048 * radix*first + second < 128 * 2^57 + 36*2^57 - radix + 36
1049 * whence
1050 * radix*first + second < 2^64 + 2^6*2^57 = 2^64 + 2^63
1051 *
1052 * E) Conditions C, D, and result >= 0:
1053 * C and D combined imply the mathematical result
1054 * 2^63 < first*radix + second < 2^64 + 2^63. The lower
1055 * bound is therefore negative as a signed long, but the
1056 * upper bound is too small to overflow again after the
1057 * signed long overflows to positive above 2^64 - 1. Hence
1058 * result >= 0 implies overflow given C and D.
1059 */
1060 throw new NumberFormatException(String.format("String value %s exceeds " +
1061 "range of unsigned long.", s.subSequence(start, start + len)));
1062 }
1063 return result;
1064 }
1065 } else {
1066 throw NumberFormatException.forInputString("");
1067 }
1068 }
1069
1070 /**
1071 * Parses the string argument as an unsigned decimal {@code long}. The
1072 * characters in the string must all be decimal digits, except
1073 * that the first character may be an ASCII plus sign {@code
1074 * '+'} ({@code '\u005Cu002B'}). The resulting integer value
1075 * is returned, exactly as if the argument and the radix 10 were
1076 * given as arguments to the {@link
1077 * #parseUnsignedLong(java.lang.String, int)} method.
1078 *
1079 * @param s a {@code String} containing the unsigned {@code long}
1080 * representation to be parsed
1081 * @return the unsigned {@code long} value represented by the decimal string argument
1082 * @throws NumberFormatException if the string does not contain a
1083 * parsable unsigned integer.
1084 * @since 1.8
1085 */
1086 public static long parseUnsignedLong(String s) throws NumberFormatException {
|
658 if (radix < Character.MIN_RADIX) {
659 throw new NumberFormatException("radix " + radix +
660 " less than Character.MIN_RADIX");
661 }
662 if (radix > Character.MAX_RADIX) {
663 throw new NumberFormatException("radix " + radix +
664 " greater than Character.MAX_RADIX");
665 }
666
667 boolean negative = false;
668 int i = 0, len = s.length();
669 long limit = -Long.MAX_VALUE;
670
671 if (len > 0) {
672 char firstChar = s.charAt(0);
673 if (firstChar < '0') { // Possible leading "+" or "-"
674 if (firstChar == '-') {
675 negative = true;
676 limit = Long.MIN_VALUE;
677 } else if (firstChar != '+') {
678 throw NumberFormatException.forInputString(s, radix);
679 }
680
681 if (len == 1) { // Cannot have lone "+" or "-"
682 throw NumberFormatException.forInputString(s, radix);
683 }
684 i++;
685 }
686 long multmin = limit / radix;
687 long result = 0;
688 while (i < len) {
689 // Accumulating negatively avoids surprises near MAX_VALUE
690 int digit = Character.digit(s.charAt(i++),radix);
691 if (digit < 0 || result < multmin) {
692 throw NumberFormatException.forInputString(s, radix);
693 }
694 result *= radix;
695 if (result < limit + digit) {
696 throw NumberFormatException.forInputString(s, radix);
697 }
698 result -= digit;
699 }
700 return negative ? result : -result;
701 } else {
702 throw NumberFormatException.forInputString(s, radix);
703 }
704 }
705
706 /**
707 * Parses the {@link CharSequence} argument as a signed {@code long} in
708 * the specified {@code radix}, beginning at the specified
709 * {@code beginIndex} and extending to {@code endIndex - 1}.
710 *
711 * <p>The method does not take steps to guard against the
712 * {@code CharSequence} being mutated while parsing.
713 *
714 * @param s the {@code CharSequence} containing the {@code long}
715 * representation to be parsed
716 * @param beginIndex the beginning index, inclusive.
717 * @param endIndex the ending index, exclusive.
718 * @param radix the radix to be used while parsing {@code s}.
719 * @return the signed {@code long} represented by the subsequence in
720 * the specified radix.
721 * @throws NullPointerException if {@code s} is null.
722 * @throws IndexOutOfBoundsException if {@code beginIndex} is
928 * radix*first + second <= (radix*left7) * 2^57 + radix*(2^57 - 1) + 36
929 * thus
930 * radix*first + second < 128 * 2^57 + 36*2^57 - radix + 36
931 * whence
932 * radix*first + second < 2^64 + 2^6*2^57 = 2^64 + 2^63
933 *
934 * E) Conditions C, D, and result >= 0:
935 * C and D combined imply the mathematical result
936 * 2^63 < first*radix + second < 2^64 + 2^63. The lower
937 * bound is therefore negative as a signed long, but the
938 * upper bound is too small to overflow again after the
939 * signed long overflows to positive above 2^64 - 1. Hence
940 * result >= 0 implies overflow given C and D.
941 */
942 throw new NumberFormatException(String.format("String value %s exceeds " +
943 "range of unsigned long.", s));
944 }
945 return result;
946 }
947 } else {
948 throw NumberFormatException.forInputString(s, radix);
949 }
950 }
951
952 /**
953 * Parses the {@link CharSequence} argument as an unsigned {@code long} in
954 * the specified {@code radix}, beginning at the specified
955 * {@code beginIndex} and extending to {@code endIndex - 1}.
956 *
957 * <p>The method does not take steps to guard against the
958 * {@code CharSequence} being mutated while parsing.
959 *
960 * @param s the {@code CharSequence} containing the unsigned
961 * {@code long} representation to be parsed
962 * @param beginIndex the beginning index, inclusive.
963 * @param endIndex the ending index, exclusive.
964 * @param radix the radix to be used while parsing {@code s}.
965 * @return the unsigned {@code long} represented by the subsequence in
966 * the specified radix.
967 * @throws NullPointerException if {@code s} is null.
968 * @throws IndexOutOfBoundsException if {@code beginIndex} is
1046 * radix*first + second <= (radix*left7) * 2^57 + radix*(2^57 - 1) + 36
1047 * thus
1048 * radix*first + second < 128 * 2^57 + 36*2^57 - radix + 36
1049 * whence
1050 * radix*first + second < 2^64 + 2^6*2^57 = 2^64 + 2^63
1051 *
1052 * E) Conditions C, D, and result >= 0:
1053 * C and D combined imply the mathematical result
1054 * 2^63 < first*radix + second < 2^64 + 2^63. The lower
1055 * bound is therefore negative as a signed long, but the
1056 * upper bound is too small to overflow again after the
1057 * signed long overflows to positive above 2^64 - 1. Hence
1058 * result >= 0 implies overflow given C and D.
1059 */
1060 throw new NumberFormatException(String.format("String value %s exceeds " +
1061 "range of unsigned long.", s.subSequence(start, start + len)));
1062 }
1063 return result;
1064 }
1065 } else {
1066 throw NumberFormatException.forInputString("", radix);
1067 }
1068 }
1069
1070 /**
1071 * Parses the string argument as an unsigned decimal {@code long}. The
1072 * characters in the string must all be decimal digits, except
1073 * that the first character may be an ASCII plus sign {@code
1074 * '+'} ({@code '\u005Cu002B'}). The resulting integer value
1075 * is returned, exactly as if the argument and the radix 10 were
1076 * given as arguments to the {@link
1077 * #parseUnsignedLong(java.lang.String, int)} method.
1078 *
1079 * @param s a {@code String} containing the unsigned {@code long}
1080 * representation to be parsed
1081 * @return the unsigned {@code long} value represented by the decimal string argument
1082 * @throws NumberFormatException if the string does not contain a
1083 * parsable unsigned integer.
1084 * @since 1.8
1085 */
1086 public static long parseUnsignedLong(String s) throws NumberFormatException {
|