/* * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.lang; import java.util.Properties; /** * The {@code Integer} class wraps a value of the primitive type * {@code int} in an object. An object of type {@code Integer} * contains a single field whose type is {@code int}. * * <p>In addition, this class provides several methods for converting * an {@code int} to a {@code String} and a {@code String} to an * {@code int}, as well as other constants and methods useful when * dealing with an {@code int}. * * <p>Implementation note: The implementations of the "bit twiddling" * methods (such as {@link #highestOneBit(int) highestOneBit} and * {@link #numberOfTrailingZeros(int) numberOfTrailingZeros}) are * based on material from Henry S. Warren, Jr.'s <i>Hacker's * Delight</i>, (Addison Wesley, 2002). * * @author Lee Boynton * @author Arthur van Hoff * @author Josh Bloch * @author Joseph D. Darcy * @since JDK1.0 */public final class Integer extends Number implements Comparable<Integer> { /** * A constant holding the minimum value an {@code int} can * have, -2<sup>31</sup>. */ public static final int MIN_VALUE = 0x80000000; /** * A constant holding the maximum value an {@code int} can * have, 2<sup>31</sup>-1. */ public static final int MAX_VALUE = 0x7fffffff; /** * The {@code Class} instance representing the primitive type * {@code int}. * * @since JDK1.1 */ public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int"); /** * All possible chars for representing a number as a String */ final static char[] digits = { '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , 'o' , 'p' , 'q' , 'r' , 's' , 't' , 'u' , 'v' , 'w' , 'x' , 'y' , 'z' }; /** * Returns a string representation of the first argument in the * radix specified by the second argument. * * <p>If the radix is smaller than {@code Character.MIN_RADIX} * or larger than {@code Character.MAX_RADIX}, then the radix * {@code 10} is used instead. * * <p>If the first argument is negative, the first element of the * result is the ASCII minus character {@code '-'} * (<code>'\u002D'</code>). If the first argument is not * negative, no sign character appears in the result. * * <p>The remaining characters of the result represent the magnitude * of the first argument. If the magnitude is zero, it is * represented by a single zero character {@code '0'} * (<code>'\u0030'</code>); otherwise, the first character of * the representation of the magnitude will not be the zero * character. The following ASCII characters are used as digits: * * <blockquote> * {@code 0123456789abcdefghijklmnopqrstuvwxyz} * </blockquote> * * These are <code>'\u0030'</code> through * <code>'\u0039'</code> and <code>'\u0061'</code> through * <code>'\u007A'</code>. If {@code radix} is * <var>N</var>, then the first <var>N</var> of these characters * are used as radix-<var>N</var> digits in the order shown. Thus, * the digits for hexadecimal (radix 16) are * {@code 0123456789abcdef}. If uppercase letters are * desired, the {@link java.lang.String#toUpperCase()} method may * be called on the result: * * <blockquote> * {@code Integer.toString(n, 16).toUpperCase()} * </blockquote> * * @param i an integer to be converted to a string. * @param radix the radix to use in the string representation. * @return a string representation of the argument in the specified radix. * @see java.lang.Character#MAX_RADIX * @see java.lang.Character#MIN_RADIX */ public static String toString(int i, int radix) { if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) radix = 10; /* Use the faster version */ if (radix == 10) { return toString(i); } char buf[] = new char[33]; boolean negative = (i < 0); int charPos = 32; if (!negative) { i = -i; } while (i <= -radix) { buf[charPos--] = digits[-(i % radix)]; i = i / radix; } buf[charPos] = digits[-i]; if (negative) { buf[--charPos] = '-'; } return new String(buf, charPos, (33 - charPos)); } /** * Returns a string representation of the integer argument as an * unsigned integer in base 16. * * <p>The unsigned integer value is the argument plus 2<sup>32</sup> * if the argument is negative; otherwise, it is equal to the * argument. This value is converted to a string of ASCII digits * in hexadecimal (base 16) with no extra leading * {@code 0}s. If the unsigned magnitude is zero, it is * represented by a single zero character {@code '0'} * (<code>'\u0030'</code>); otherwise, the first character of * the representation of the unsigned magnitude will not be the * zero character. The following characters are used as * hexadecimal digits: * * <blockquote> * {@code 0123456789abcdef} * </blockquote> * * These are the characters <code>'\u0030'</code> through * <code>'\u0039'</code> and <code>'\u0061'</code> through * <code>'\u0066'</code>. If uppercase letters are * desired, the {@link java.lang.String#toUpperCase()} method may * be called on the result: * * <blockquote> * {@code Integer.toHexString(n).toUpperCase()} * </blockquote> * * @param i an integer to be converted to a string. * @return the string representation of the unsigned integer value * represented by the argument in hexadecimal (base 16). * @since JDK1.0.2 */ public static String toHexString(int i) { return toUnsignedString(i, 4); } /** * Returns a string representation of the integer argument as an * unsigned integer in base 8. * * <p>The unsigned integer value is the argument plus 2<sup>32</sup> * if the argument is negative; otherwise, it is equal to the * argument. This value is converted to a string of ASCII digits * in octal (base 8) with no extra leading {@code 0}s. * * <p>If the unsigned magnitude is zero, it is represented by a * single zero character {@code '0'} * (<code>'\u0030'</code>); otherwise, the first character of * the representation of the unsigned magnitude will not be the * zero character. The following characters are used as octal * digits: * * <blockquote> * {@code 01234567} * </blockquote> * * These are the characters <code>'\u0030'</code> through * <code>'\u0037'</code>. * * @param i an integer to be converted to a string. * @return the string representation of the unsigned integer value * represented by the argument in octal (base 8). * @since JDK1.0.2 */ public static String toOctalString(int i) { return toUnsignedString(i, 3); } /** * Returns a string representation of the integer argument as an * unsigned integer in base 2. * * <p>The unsigned integer value is the argument plus 2<sup>32</sup> * if the argument is negative; otherwise it is equal to the * argument. This value is converted to a string of ASCII digits * in binary (base 2) with no extra leading {@code 0}s. * If the unsigned magnitude is zero, it is represented by a * single zero character {@code '0'} * (<code>'\u0030'</code>); otherwise, the first character of * the representation of the unsigned magnitude will not be the * zero character. The characters {@code '0'} * (<code>'\u0030'</code>) and {@code '1'} * (<code>'\u0031'</code>) are used as binary digits. * * @param i an integer to be converted to a string. * @return the string representation of the unsigned integer value * represented by the argument in binary (base 2). * @since JDK1.0.2 */ public static String toBinaryString(int i) { return toUnsignedString(i, 1); } /** * Convert the integer to an unsigned number. */ private static String toUnsignedString(int i, int shift) { char[] buf = new char[32]; int charPos = 32; int radix = 1 << shift; int mask = radix - 1; do { buf[--charPos] = digits[i & mask]; i >>>= shift; } while (i != 0); return new String(buf, charPos, (32 - charPos)); } final static char [] DigitTens = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', } ; final static char [] DigitOnes = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', } ; // I use the "invariant division by multiplication" trick to // accelerate Integer.toString. In particular we want to // avoid division by 10. // // The "trick" has roughly the same performance characteristics // as the "classic" Integer.toString code on a non-JIT VM. // The trick avoids .rem and .div calls but has a longer code // path and is thus dominated by dispatch overhead. In the // JIT case the dispatch overhead doesn't exist and the // "trick" is considerably faster than the classic code. // // TODO-FIXME: convert (x * 52429) into the equiv shift-add // sequence. // // RE: Division by Invariant Integers using Multiplication // T Gralund, P Montgomery // ACM PLDI 1994 // /** * Returns a {@code String} object representing the * specified integer. The argument is converted to signed decimal * representation and returned as a string, exactly as if the * argument and radix 10 were given as arguments to the {@link * #toString(int, int)} method. * * @param i an integer to be converted. * @return a string representation of the argument in base 10. */ public static String toString(int i) { if (i == Integer.MIN_VALUE) return "-2147483648"; int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); char[] buf = new char[size]; getChars(i, size, buf); return new String(0, size, buf); } /** * Places characters representing the integer i into the * character array buf. The characters are placed into * the buffer backwards starting with the least significant * digit at the specified index (exclusive), and working * backwards from there. * * Will fail if i == Integer.MIN_VALUE */ static void getChars(int i, int index, char[] buf) { int q, r; int charPos = index; char sign = 0; if (i < 0) { sign = '-'; i = -i; } // Generate two digits per iteration while (i >= 65536) { q = i / 100; // really: r = i - (q * 100); r = i - ((q << 6) + (q << 5) + (q << 2)); i = q; buf [--charPos] = DigitOnes[r]; buf [--charPos] = DigitTens[r]; } // Fall thru to fast mode for smaller numbers // assert(i <= 65536, i); for (;;) { q = (i * 52429) >>> (16+3); r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ... buf [--charPos] = digits [r]; i = q; if (i == 0) break; } if (sign != 0) { buf [--charPos] = sign; } } final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE }; // Requires positive x static int stringSize(int x) { for (int i=0; ; i++) if (x <= sizeTable[i]) return i+1; } /** * Parses the string argument as a signed integer in the radix * specified by the second argument. The characters in the string * must all be digits of the specified radix (as determined by * whether {@link java.lang.Character#digit(char, int)} returns a * nonnegative value), except that the first character may be an * ASCII minus sign {@code '-'} (<code>'\u002D'</code>) to * indicate a negative value or an ASCII plus sign {@code '+'} * (<code>'\u002B'</code>) to indicate a positive value. The * resulting integer value is returned. * * <p>An exception of type {@code NumberFormatException} is * thrown if any of the following situations occurs: * <ul> * <li>The first argument is {@code null} or is a string of * length zero. * * <li>The radix is either smaller than * {@link java.lang.Character#MIN_RADIX} or * larger than {@link java.lang.Character#MAX_RADIX}. * * <li>Any character of the string is not a digit of the specified * radix, except that the first character may be a minus sign * {@code '-'} (<code>'\u002D'</code>) or plus sign * {@code '+'} (<code>'\u002B'</code>) provided that the * string is longer than length 1. * * <li>The value represented by the string is not a value of type * {@code int}. * </ul> * * <p>Examples: * <blockquote><pre> * parseInt("0", 10) returns 0 * parseInt("473", 10) returns 473 * parseInt("+42", 10) returns 42 * parseInt("-0", 10) returns 0 * parseInt("-FF", 16) returns -255 * parseInt("1100110", 2) returns 102 * parseInt("2147483647", 10) returns 2147483647 * parseInt("-2147483648", 10) returns -2147483648 * parseInt("2147483648", 10) throws a NumberFormatException * parseInt("99", 8) throws a NumberFormatException * parseInt("Kona", 10) throws a NumberFormatException * parseInt("Kona", 27) returns 411787 * </pre></blockquote> * * @param s the {@code String} containing the integer * representation to be parsed * @param radix the radix to be used while parsing {@code s}. * @return the integer represented by the string argument in the * specified radix. * @exception NumberFormatException if the {@code String} * does not contain a parsable {@code int}. */ public static int parseInt(String s, int radix) throws NumberFormatException { /* * WARNING: This method may be invoked early during VM initialization * before IntegerCache is initialized. Care must be taken to not use * the valueOf method. */ if (s == null) { throw new NumberFormatException("null"); } if (radix < Character.MIN_RADIX) { throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX"); } if (radix > Character.MAX_RADIX) { throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX"); } int result = 0; boolean negative = false; int i = 0, len = s.length(); int limit = -Integer.MAX_VALUE; int multmin; int digit; if (len > 0) { char firstChar = s.charAt(0); if (firstChar < '0') { // Possible leading "+" or "-" if (firstChar == '-') { negative = true; limit = Integer.MIN_VALUE; } else if (firstChar != '+') throw NumberFormatException.forInputString(s); if (len == 1) // Cannot have lone "+" or "-" throw NumberFormatException.forInputString(s); i++; } multmin = limit / radix; while (i < len) { // Accumulating negatively avoids surprises near MAX_VALUE digit = Character.digit(s.charAt(i++),radix); if (digit < 0) { throw NumberFormatException.forInputString(s); } if (result < multmin) { throw NumberFormatException.forInputString(s); } result *= radix; if (result < limit + digit) { throw NumberFormatException.forInputString(s); }Lines 1–500 of 1244. Load more
/* * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.lang; import java.util.Properties; /** * The {@code Integer} class wraps a value of the primitive type * {@code int} in an object. An object of type {@code Integer} * contains a single field whose type is {@code int}. * * <p>In addition, this class provides several methods for converting * an {@code int} to a {@code String} and a {@code String} to an * {@code int}, as well as other constants and methods useful when * dealing with an {@code int}. * * <p>Implementation note: The implementations of the "bit twiddling" * methods (such as {@link #highestOneBit(int) highestOneBit} and * {@link #numberOfTrailingZeros(int) numberOfTrailingZeros}) are * based on material from Henry S. Warren, Jr.'s <i>Hacker's * Delight</i>, (Addison Wesley, 2002). * * @author Lee Boynton * @author Arthur van Hoff * @author Josh Bloch * @author Joseph D. Darcy * @since JDK1.0 */ public final class Integer extends Number implements Comparable<Integer> { /** * A constant holding the minimum value an {@code int} can * have, -2<sup>31</sup>. */ public static final int MIN_VALUE = 0x80000000; /** * A constant holding the maximum value an {@code int} can * have, 2<sup>31</sup>-1. */ public static final int MAX_VALUE = 0x7fffffff; /** * The {@code Class} instance representing the primitive type * {@code int}. * * @since JDK1.1 */ public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int"); /** * All possible chars for representing a number as a String */ final static char[] digits = { '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' , 'j' , 'k' , 'l' , 'm' , 'n' , 'o' , 'p' , 'q' , 'r' , 's' , 't' , 'u' , 'v' , 'w' , 'x' , 'y' , 'z' }; /** * Returns a string representation of the first argument in the * radix specified by the second argument. * * <p>If the radix is smaller than {@code Character.MIN_RADIX} * or larger than {@code Character.MAX_RADIX}, then the radix * {@code 10} is used instead. * * <p>If the first argument is negative, the first element of the * result is the ASCII minus character {@code '-'} * (<code>'\u002D'</code>). If the first argument is not * negative, no sign character appears in the result. * * <p>The remaining characters of the result represent the magnitude * of the first argument. If the magnitude is zero, it is * represented by a single zero character {@code '0'} * (<code>'\u0030'</code>); otherwise, the first character of * the representation of the magnitude will not be the zero * character. The following ASCII characters are used as digits: * * <blockquote> * {@code 0123456789abcdefghijklmnopqrstuvwxyz} * </blockquote> * * These are <code>'\u0030'</code> through * <code>'\u0039'</code> and <code>'\u0061'</code> through * <code>'\u007A'</code>. If {@code radix} is * <var>N</var>, then the first <var>N</var> of these characters * are used as radix-<var>N</var> digits in the order shown. Thus, * the digits for hexadecimal (radix 16) are * {@code 0123456789abcdef}. If uppercase letters are * desired, the {@link java.lang.String#toUpperCase()} method may * be called on the result: * * <blockquote> * {@code Integer.toString(n, 16).toUpperCase()} * </blockquote> * * @param i an integer to be converted to a string. * @param radix the radix to use in the string representation. * @return a string representation of the argument in the specified radix. * @see java.lang.Character#MAX_RADIX * @see java.lang.Character#MIN_RADIX */ public static String toString(int i, int radix) { if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) radix = 10; /* Use the faster version */ if (radix == 10) { return toString(i); } char buf[] = new char[33]; boolean negative = (i < 0); int charPos = 32; if (!negative) { i = -i; } while (i <= -radix) { buf[charPos--] = digits[-(i % radix)]; i = i / radix; } buf[charPos] = digits[-i]; if (negative) { buf[--charPos] = '-'; } return new String(buf, charPos, (33 - charPos)); } /** * Returns a string representation of the integer argument as an * unsigned integer in base 16. * * <p>The unsigned integer value is the argument plus 2<sup>32</sup> * if the argument is negative; otherwise, it is equal to the * argument. This value is converted to a string of ASCII digits * in hexadecimal (base 16) with no extra leading * {@code 0}s. If the unsigned magnitude is zero, it is * represented by a single zero character {@code '0'} * (<code>'\u0030'</code>); otherwise, the first character of * the representation of the unsigned magnitude will not be the * zero character. The following characters are used as * hexadecimal digits: * * <blockquote> * {@code 0123456789abcdef} * </blockquote> * * These are the characters <code>'\u0030'</code> through * <code>'\u0039'</code> and <code>'\u0061'</code> through * <code>'\u0066'</code>. If uppercase letters are * desired, the {@link java.lang.String#toUpperCase()} method may * be called on the result: * * <blockquote> * {@code Integer.toHexString(n).toUpperCase()} * </blockquote> * * @param i an integer to be converted to a string. * @return the string representation of the unsigned integer value * represented by the argument in hexadecimal (base 16). * @since JDK1.0.2 */ public static String toHexString(int i) { return toUnsignedString(i, 4); } /** * Returns a string representation of the integer argument as an * unsigned integer in base 8. * * <p>The unsigned integer value is the argument plus 2<sup>32</sup> * if the argument is negative; otherwise, it is equal to the * argument. This value is converted to a string of ASCII digits * in octal (base 8) with no extra leading {@code 0}s. * * <p>If the unsigned magnitude is zero, it is represented by a * single zero character {@code '0'} * (<code>'\u0030'</code>); otherwise, the first character of * the representation of the unsigned magnitude will not be the * zero character. The following characters are used as octal * digits: * * <blockquote> * {@code 01234567} * </blockquote> * * These are the characters <code>'\u0030'</code> through * <code>'\u0037'</code>. * * @param i an integer to be converted to a string. * @return the string representation of the unsigned integer value * represented by the argument in octal (base 8). * @since JDK1.0.2 */ public static String toOctalString(int i) { return toUnsignedString(i, 3); } /** * Returns a string representation of the integer argument as an * unsigned integer in base 2. * * <p>The unsigned integer value is the argument plus 2<sup>32</sup> * if the argument is negative; otherwise it is equal to the * argument. This value is converted to a string of ASCII digits * in binary (base 2) with no extra leading {@code 0}s. * If the unsigned magnitude is zero, it is represented by a * single zero character {@code '0'} * (<code>'\u0030'</code>); otherwise, the first character of * the representation of the unsigned magnitude will not be the * zero character. The characters {@code '0'} * (<code>'\u0030'</code>) and {@code '1'} * (<code>'\u0031'</code>) are used as binary digits. * * @param i an integer to be converted to a string. * @return the string representation of the unsigned integer value * represented by the argument in binary (base 2). * @since JDK1.0.2 */ public static String toBinaryString(int i) { return toUnsignedString(i, 1); } /** * Convert the integer to an unsigned number. */ private static String toUnsignedString(int i, int shift) { char[] buf = new char[32]; int charPos = 32; int radix = 1 << shift; int mask = radix - 1; do { buf[--charPos] = digits[i & mask]; i >>>= shift; } while (i != 0); return new String(buf, charPos, (32 - charPos)); } final static char [] DigitTens = { '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', } ; final static char [] DigitOnes = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', } ; // I use the "invariant division by multiplication" trick to // accelerate Integer.toString. In particular we want to // avoid division by 10. // // The "trick" has roughly the same performance characteristics // as the "classic" Integer.toString code on a non-JIT VM. // The trick avoids .rem and .div calls but has a longer code // path and is thus dominated by dispatch overhead. In the // JIT case the dispatch overhead doesn't exist and the // "trick" is considerably faster than the classic code. // // TODO-FIXME: convert (x * 52429) into the equiv shift-add // sequence. // // RE: Division by Invariant Integers using Multiplication // T Gralund, P Montgomery // ACM PLDI 1994 // /** * Returns a {@code String} object representing the * specified integer. The argument is converted to signed decimal * representation and returned as a string, exactly as if the * argument and radix 10 were given as arguments to the {@link * #toString(int, int)} method. * * @param i an integer to be converted. * @return a string representation of the argument in base 10. */ public static String toString(int i) { if (i == Integer.MIN_VALUE) return "-2147483648"; int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); char[] buf = new char[size]; getChars(i, size, buf); return new String(0, size, buf); } /** * Places characters representing the integer i into the * character array buf. The characters are placed into * the buffer backwards starting with the least significant * digit at the specified index (exclusive), and working * backwards from there. * * Will fail if i == Integer.MIN_VALUE */ static void getChars(int i, int index, char[] buf) { int q, r; int charPos = index; char sign = 0; if (i < 0) { sign = '-'; i = -i; } // Generate two digits per iteration while (i >= 65536) { q = i / 100; // really: r = i - (q * 100); r = i - ((q << 6) + (q << 5) + (q << 2)); i = q; buf [--charPos] = DigitOnes[r]; buf [--charPos] = DigitTens[r]; } // Fall thru to fast mode for smaller numbers // assert(i <= 65536, i); for (;;) { q = (i * 52429) >>> (16+3); r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ... buf [--charPos] = digits [r]; i = q; if (i == 0) break; } if (sign != 0) { buf [--charPos] = sign; } } final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE }; // Requires positive x static int stringSize(int x) { for (int i=0; ; i++) if (x <= sizeTable[i]) return i+1; } /** * Parses the string argument as a signed integer in the radix * specified by the second argument. The characters in the string * must all be digits of the specified radix (as determined by * whether {@link java.lang.Character#digit(char, int)} returns a * nonnegative value), except that the first character may be an * ASCII minus sign {@code '-'} (<code>'\u002D'</code>) to * indicate a negative value or an ASCII plus sign {@code '+'} * (<code>'\u002B'</code>) to indicate a positive value. The * resulting integer value is returned. * * <p>An exception of type {@code NumberFormatException} is * thrown if any of the following situations occurs: * <ul> * <li>The first argument is {@code null} or is a string of * length zero. * * <li>The radix is either smaller than * {@link java.lang.Character#MIN_RADIX} or * larger than {@link java.lang.Character#MAX_RADIX}. * * <li>Any character of the string is not a digit of the specified * radix, except that the first character may be a minus sign * {@code '-'} (<code>'\u002D'</code>) or plus sign * {@code '+'} (<code>'\u002B'</code>) provided that the * string is longer than length 1. * * <li>The value represented by the string is not a value of type * {@code int}. * </ul> * * <p>Examples: * <blockquote><pre> * parseInt("0", 10) returns 0 * parseInt("473", 10) returns 473 * parseInt("+42", 10) returns 42 * parseInt("-0", 10) returns 0 * parseInt("-FF", 16) returns -255 * parseInt("1100110", 2) returns 102 * parseInt("2147483647", 10) returns 2147483647 * parseInt("-2147483648", 10) returns -2147483648 * parseInt("2147483648", 10) throws a NumberFormatException * parseInt("99", 8) throws a NumberFormatException * parseInt("Kona", 10) throws a NumberFormatException * parseInt("Kona", 27) returns 411787 * </pre></blockquote> * * @param s the {@code String} containing the integer * representation to be parsed * @param radix the radix to be used while parsing {@code s}. * @return the integer represented by the string argument in the * specified radix. * @exception NumberFormatException if the {@code String} * does not contain a parsable {@code int}. */ public static int parseInt(String s, int radix) throws NumberFormatException { /* * WARNING: This method may be invoked early during VM initialization * before IntegerCache is initialized. Care must be taken to not use * the valueOf method. */ if (s == null) { throw new NumberFormatException("null"); } if (radix < Character.MIN_RADIX) { throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX"); } if (radix > Character.MAX_RADIX) { throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX"); } int result = 0; boolean negative = false; int i = 0, len = s.length(); int limit = -Integer.MAX_VALUE; int multmin; int digit; if (len > 0) { char firstChar = s.charAt(0); if (firstChar < '0') { // Possible leading "+" or "-" if (firstChar == '-') { negative = true; limit = Integer.MIN_VALUE; } else if (firstChar != '+') throw NumberFormatException.forInputString(s); if (len == 1) // Cannot have lone "+" or "-" throw NumberFormatException.forInputString(s); i++; } multmin = limit / radix; while (i < len) { // Accumulating negatively avoids surprises near MAX_VALUE digit = Character.digit(s.charAt(i++),radix); if (digit < 0) { throw NumberFormatException.forInputString(s); } if (result < multmin) { throw NumberFormatException.forInputString(s); } result *= radix; if (result < limit + digit) { throw NumberFormatException.forInputString(s); }