Frames | No Frames |
1: /* Integer.java -- object wrapper for int 2: Copyright (C) 1998, 1999, 2001, 2002, 2004, 2005 3: Free Software Foundation, Inc. 4: 5: This file is part of GNU Classpath. 6: 7: GNU Classpath is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU Classpath is distributed in the hope that it will be useful, but 13: WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15: General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU Classpath; see the file COPYING. If not, write to the 19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20: 02110-1301 USA. 21: 22: Linking this library statically or dynamically with other modules is 23: making a combined work based on this library. Thus, the terms and 24: conditions of the GNU General Public License cover the whole 25: combination. 26: 27: As a special exception, the copyright holders of this library give you 28: permission to link this library with independent modules to produce an 29: executable, regardless of the license terms of these independent 30: modules, and to copy and distribute the resulting executable under 31: terms of your choice, provided that you also meet, for each linked 32: independent module, the terms and conditions of the license of that 33: module. An independent module is a module which is not derived from 34: or based on this library. If you modify this library, you may extend 35: this exception to your version of the library, but you are not 36: obligated to do so. If you do not wish to do so, delete this 37: exception statement from your version. */ 38: 39: 40: package java.lang; 41: 42: /** 43: * Instances of class <code>Integer</code> represent primitive 44: * <code>int</code> values. 45: * 46: * Additionally, this class provides various helper functions and variables 47: * related to ints. 48: * 49: * @author Paul Fisher 50: * @author John Keiser 51: * @author Warren Levy 52: * @author Eric Blake (ebb9@email.byu.edu) 53: * @author Tom Tromey (tromey@redhat.com) 54: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 55: * @author Ian Rogers 56: * @since 1.0 57: * @status updated to 1.5 58: */ 59: public final class Integer extends Number implements Comparable<Integer> 60: { 61: /** 62: * Compatible with JDK 1.0.2+. 63: */ 64: private static final long serialVersionUID = 1360826667806852920L; 65: 66: /** 67: * The minimum value an <code>int</code> can represent is -2147483648 (or 68: * -2<sup>31</sup>). 69: */ 70: public static final int MIN_VALUE = 0x80000000; 71: 72: /** 73: * The maximum value an <code>int</code> can represent is 2147483647 (or 74: * 2<sup>31</sup> - 1). 75: */ 76: public static final int MAX_VALUE = 0x7fffffff; 77: 78: /** 79: * The primitive type <code>int</code> is represented by this 80: * <code>Class</code> object. 81: * @since 1.1 82: */ 83: public static final Class<Integer> TYPE = (Class<Integer>) VMClassLoader.getPrimitiveClass('I'); 84: 85: /** 86: * The number of bits needed to represent an <code>int</code>. 87: * @since 1.5 88: */ 89: public static final int SIZE = 32; 90: 91: // This caches some Integer values, and is used by boxing 92: // conversions via valueOf(). We must cache at least -128..127; 93: // these constants control how much we actually cache. 94: private static final int MIN_CACHE = -128; 95: private static final int MAX_CACHE = 127; 96: private static final Integer[] intCache = new Integer[MAX_CACHE - MIN_CACHE + 1]; 97: static 98: { 99: for (int i=MIN_CACHE; i <= MAX_CACHE; i++) 100: intCache[i - MIN_CACHE] = new Integer(i); 101: } 102: 103: /** 104: * The immutable value of this Integer. 105: * 106: * @serial the wrapped int 107: */ 108: private final int value; 109: 110: /** 111: * Create an <code>Integer</code> object representing the value of the 112: * <code>int</code> argument. 113: * 114: * @param value the value to use 115: */ 116: public Integer(int value) 117: { 118: this.value = value; 119: } 120: 121: /** 122: * Create an <code>Integer</code> object representing the value of the 123: * argument after conversion to an <code>int</code>. 124: * 125: * @param s the string to convert 126: * @throws NumberFormatException if the String does not contain an int 127: * @see #valueOf(String) 128: */ 129: public Integer(String s) 130: { 131: value = parseInt(s, 10, false); 132: } 133: 134: /** 135: * Return the size of a string large enough to hold the given number 136: * 137: * @param num the number we want the string length for (must be positive) 138: * @param radix the radix (base) that will be used for the string 139: * @return a size sufficient for a string of num 140: */ 141: private static int stringSize(int num, int radix) { 142: int exp; 143: if (radix < 4) 144: { 145: exp = 1; 146: } 147: else if (radix < 8) 148: { 149: exp = 2; 150: } 151: else if (radix < 16) 152: { 153: exp = 3; 154: } 155: else if (radix < 32) 156: { 157: exp = 4; 158: } 159: else 160: { 161: exp = 5; 162: } 163: int size=0; 164: do 165: { 166: num >>>= exp; 167: size++; 168: } 169: while(num != 0); 170: return size; 171: } 172: 173: /** 174: * Converts the <code>int</code> to a <code>String</code> using 175: * the specified radix (base). If the radix exceeds 176: * <code>Character.MIN_RADIX</code> or <code>Character.MAX_RADIX</code>, 10 177: * is used instead. If the result is negative, the leading character is 178: * '-' ('\\u002D'). The remaining characters come from 179: * <code>Character.forDigit(digit, radix)</code> ('0'-'9','a'-'z'). 180: * 181: * @param num the <code>int</code> to convert to <code>String</code> 182: * @param radix the radix (base) to use in the conversion 183: * @return the <code>String</code> representation of the argument 184: */ 185: public static String toString(int num, int radix) 186: { 187: if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) 188: radix = 10; 189: 190: // Is the value negative? 191: boolean isNeg = num < 0; 192: 193: // Is the string a single character? 194: if (!isNeg && num < radix) 195: return new String(digits, num, 1, true); 196: 197: // Compute string size and allocate buffer 198: // account for a leading '-' if the value is negative 199: int size; 200: int i; 201: char[] buffer; 202: if (isNeg) 203: { 204: num = -num; 205: 206: // When the value is MIN_VALUE, it overflows when made positive 207: if (num < 0) 208: { 209: i = size = stringSize(MAX_VALUE, radix) + 2; 210: buffer = new char[size]; 211: buffer[--i] = digits[(int) (-(num + radix) % radix)]; 212: num = -(num / radix); 213: } 214: else 215: { 216: i = size = stringSize(num, radix) + 1; 217: buffer = new char[size]; 218: } 219: } 220: else 221: { 222: i = size = stringSize(num, radix); 223: buffer = new char[size]; 224: } 225: 226: do 227: { 228: buffer[--i] = digits[num % radix]; 229: num /= radix; 230: } 231: while (num > 0); 232: 233: if (isNeg) 234: buffer[--i] = '-'; 235: 236: // Package constructor avoids an array copy. 237: return new String(buffer, i, size - i, true); 238: } 239: 240: /** 241: * Converts the <code>int</code> to a <code>String</code> assuming it is 242: * unsigned in base 16. 243: * 244: * @param i the <code>int</code> to convert to <code>String</code> 245: * @return the <code>String</code> representation of the argument 246: */ 247: public static String toHexString(int i) 248: { 249: return toUnsignedString(i, 4); 250: } 251: 252: /** 253: * Converts the <code>int</code> to a <code>String</code> assuming it is 254: * unsigned in base 8. 255: * 256: * @param i the <code>int</code> to convert to <code>String</code> 257: * @return the <code>String</code> representation of the argument 258: */ 259: public static String toOctalString(int i) 260: { 261: return toUnsignedString(i, 3); 262: } 263: 264: /** 265: * Converts the <code>int</code> to a <code>String</code> assuming it is 266: * unsigned in base 2. 267: * 268: * @param i the <code>int</code> to convert to <code>String</code> 269: * @return the <code>String</code> representation of the argument 270: */ 271: public static String toBinaryString(int i) 272: { 273: return toUnsignedString(i, 1); 274: } 275: 276: /** 277: * Converts the <code>int</code> to a <code>String</code> and assumes 278: * a radix of 10. 279: * 280: * @param i the <code>int</code> to convert to <code>String</code> 281: * @return the <code>String</code> representation of the argument 282: * @see #toString(int, int) 283: */ 284: public static String toString(int i) 285: { 286: // This is tricky: in libgcj, String.valueOf(int) is a fast native 287: // implementation. In Classpath it just calls back to 288: // Integer.toString(int, int). 289: return String.valueOf(i); 290: } 291: 292: /** 293: * Converts the specified <code>String</code> into an <code>int</code> 294: * using the specified radix (base). The string must not be <code>null</code> 295: * or empty. It may begin with an optional '-', which will negate the answer, 296: * provided that there are also valid digits. Each digit is parsed as if by 297: * <code>Character.digit(d, radix)</code>, and must be in the range 298: * <code>0</code> to <code>radix - 1</code>. Finally, the result must be 299: * within <code>MIN_VALUE</code> to <code>MAX_VALUE</code>, inclusive. 300: * Unlike Double.parseDouble, you may not have a leading '+'. 301: * 302: * @param str the <code>String</code> to convert 303: * @param radix the radix (base) to use in the conversion 304: * @return the <code>String</code> argument converted to <code>int</code> 305: * @throws NumberFormatException if <code>s</code> cannot be parsed as an 306: * <code>int</code> 307: */ 308: public static int parseInt(String str, int radix) 309: { 310: return parseInt(str, radix, false); 311: } 312: 313: /** 314: * Converts the specified <code>String</code> into an <code>int</code>. 315: * This function assumes a radix of 10. 316: * 317: * @param s the <code>String</code> to convert 318: * @return the <code>int</code> value of <code>s</code> 319: * @throws NumberFormatException if <code>s</code> cannot be parsed as an 320: * <code>int</code> 321: * @see #parseInt(String, int) 322: */ 323: public static int parseInt(String s) 324: { 325: return parseInt(s, 10, false); 326: } 327: 328: /** 329: * Creates a new <code>Integer</code> object using the <code>String</code> 330: * and specified radix (base). 331: * 332: * @param s the <code>String</code> to convert 333: * @param radix the radix (base) to convert with 334: * @return the new <code>Integer</code> 335: * @throws NumberFormatException if <code>s</code> cannot be parsed as an 336: * <code>int</code> 337: * @see #parseInt(String, int) 338: */ 339: public static Integer valueOf(String s, int radix) 340: { 341: return valueOf(parseInt(s, radix, false)); 342: } 343: 344: /** 345: * Creates a new <code>Integer</code> object using the <code>String</code>, 346: * assuming a radix of 10. 347: * 348: * @param s the <code>String</code> to convert 349: * @return the new <code>Integer</code> 350: * @throws NumberFormatException if <code>s</code> cannot be parsed as an 351: * <code>int</code> 352: * @see #Integer(String) 353: * @see #parseInt(String) 354: */ 355: public static Integer valueOf(String s) 356: { 357: return valueOf(parseInt(s, 10, false)); 358: } 359: 360: /** 361: * Returns an <code>Integer</code> object wrapping the value. 362: * In contrast to the <code>Integer</code> constructor, this method 363: * will cache some values. It is used by boxing conversion. 364: * 365: * @param val the value to wrap 366: * @return the <code>Integer</code> 367: */ 368: public static Integer valueOf(int val) 369: { 370: if (val < MIN_CACHE || val > MAX_CACHE) 371: return new Integer(val); 372: else 373: return intCache[val - MIN_CACHE]; 374: } 375: 376: /** 377: * Return the value of this <code>Integer</code> as a <code>byte</code>. 378: * 379: * @return the byte value 380: */ 381: public byte byteValue() 382: { 383: return (byte) value; 384: } 385: 386: /** 387: * Return the value of this <code>Integer</code> as a <code>short</code>. 388: * 389: * @return the short value 390: */ 391: public short shortValue() 392: { 393: return (short) value; 394: } 395: 396: /** 397: * Return the value of this <code>Integer</code>. 398: * @return the int value 399: */ 400: public int intValue() 401: { 402: return value; 403: } 404: 405: /** 406: * Return the value of this <code>Integer</code> as a <code>long</code>. 407: * 408: * @return the long value 409: */ 410: public long longValue() 411: { 412: return value; 413: } 414: 415: /** 416: * Return the value of this <code>Integer</code> as a <code>float</code>. 417: * 418: * @return the float value 419: */ 420: public float floatValue() 421: { 422: return value; 423: } 424: 425: /** 426: * Return the value of this <code>Integer</code> as a <code>double</code>. 427: * 428: * @return the double value 429: */ 430: public double doubleValue() 431: { 432: return value; 433: } 434: 435: /** 436: * Converts the <code>Integer</code> value to a <code>String</code> and 437: * assumes a radix of 10. 438: * 439: * @return the <code>String</code> representation 440: */ 441: public String toString() 442: { 443: return String.valueOf(value); 444: } 445: 446: /** 447: * Return a hashcode representing this Object. <code>Integer</code>'s hash 448: * code is simply its value. 449: * 450: * @return this Object's hash code 451: */ 452: public int hashCode() 453: { 454: return value; 455: } 456: 457: /** 458: * Returns <code>true</code> if <code>obj</code> is an instance of 459: * <code>Integer</code> and represents the same int value. 460: * 461: * @param obj the object to compare 462: * @return whether these Objects are semantically equal 463: */ 464: public boolean equals(Object obj) 465: { 466: return obj instanceof Integer && value == ((Integer) obj).value; 467: } 468: 469: /** 470: * Get the specified system property as an <code>Integer</code>. The 471: * <code>decode()</code> method will be used to interpret the value of 472: * the property. 473: * 474: * @param nm the name of the system property 475: * @return the system property as an <code>Integer</code>, or null if the 476: * property is not found or cannot be decoded 477: * @throws SecurityException if accessing the system property is forbidden 478: * @see System#getProperty(String) 479: * @see #decode(String) 480: */ 481: public static Integer getInteger(String nm) 482: { 483: return getInteger(nm, null); 484: } 485: 486: /** 487: * Get the specified system property as an <code>Integer</code>, or use a 488: * default <code>int</code> value if the property is not found or is not 489: * decodable. The <code>decode()</code> method will be used to interpret 490: * the value of the property. 491: * 492: * @param nm the name of the system property 493: * @param val the default value 494: * @return the value of the system property, or the default 495: * @throws SecurityException if accessing the system property is forbidden 496: * @see System#getProperty(String) 497: * @see #decode(String) 498: */ 499: public static Integer getInteger(String nm, int val) 500: { 501: Integer result = getInteger(nm, null); 502: return result == null ? valueOf(val) : result; 503: } 504: 505: /** 506: * Get the specified system property as an <code>Integer</code>, or use a 507: * default <code>Integer</code> value if the property is not found or is 508: * not decodable. The <code>decode()</code> method will be used to 509: * interpret the value of the property. 510: * 511: * @param nm the name of the system property 512: * @param def the default value 513: * @return the value of the system property, or the default 514: * @throws SecurityException if accessing the system property is forbidden 515: * @see System#getProperty(String) 516: * @see #decode(String) 517: */ 518: public static Integer getInteger(String nm, Integer def) 519: { 520: if (nm == null || "".equals(nm)) 521: return def; 522: nm = System.getProperty(nm); 523: if (nm == null) 524: return def; 525: try 526: { 527: return decode(nm); 528: } 529: catch (NumberFormatException e) 530: { 531: return def; 532: } 533: } 534: 535: /** 536: * Convert the specified <code>String</code> into an <code>Integer</code>. 537: * The <code>String</code> may represent decimal, hexadecimal, or 538: * octal numbers. 539: * 540: * <p>The extended BNF grammar is as follows:<br> 541: * <pre> 542: * <em>DecodableString</em>: 543: * ( [ <code>-</code> ] <em>DecimalNumber</em> ) 544: * | ( [ <code>-</code> ] ( <code>0x</code> | <code>0X</code> 545: * | <code>#</code> ) <em>HexDigit</em> { <em>HexDigit</em> } ) 546: * | ( [ <code>-</code> ] <code>0</code> { <em>OctalDigit</em> } ) 547: * <em>DecimalNumber</em>: 548: * <em>DecimalDigit except '0'</em> { <em>DecimalDigit</em> } 549: * <em>DecimalDigit</em>: 550: * <em>Character.digit(d, 10) has value 0 to 9</em> 551: * <em>OctalDigit</em>: 552: * <em>Character.digit(d, 8) has value 0 to 7</em> 553: * <em>DecimalDigit</em>: 554: * <em>Character.digit(d, 16) has value 0 to 15</em> 555: * </pre> 556: * Finally, the value must be in the range <code>MIN_VALUE</code> to 557: * <code>MAX_VALUE</code>, or an exception is thrown. 558: * 559: * @param str the <code>String</code> to interpret 560: * @return the value of the String as an <code>Integer</code> 561: * @throws NumberFormatException if <code>s</code> cannot be parsed as a 562: * <code>int</code> 563: * @throws NullPointerException if <code>s</code> is null 564: * @since 1.2 565: */ 566: public static Integer decode(String str) 567: { 568: return valueOf(parseInt(str, 10, true)); 569: } 570: 571: /** 572: * Compare two Integers numerically by comparing their <code>int</code> 573: * values. The result is positive if the first is greater, negative if the 574: * second is greater, and 0 if the two are equal. 575: * 576: * @param i the Integer to compare 577: * @return the comparison 578: * @since 1.2 579: */ 580: public int compareTo(Integer i) 581: { 582: if (value == i.value) 583: return 0; 584: // Returns just -1 or 1 on inequality; doing math might overflow. 585: return value > i.value ? 1 : -1; 586: } 587: 588: /** 589: * Compares two unboxed int values. 590: * The result is positive if the first is greater, negative if the second 591: * is greater, and 0 if the two are equal. 592: * 593: * @param x First value to compare. 594: * @param y Second value to compare. 595: * 596: * @return positive int if the first value is greater, negative if the second 597: * is greater, and 0 if the two are equal. 598: * @since 1.7 599: */ 600: public static int compare(int x, int y) 601: { 602: return Integer.valueOf(x).compareTo(Integer.valueOf(y)); 603: } 604: 605: /** 606: * Return the number of bits set in x. 607: * @param x value to examine 608: * @since 1.5 609: */ 610: public static int bitCount(int x) 611: { 612: // Successively collapse alternating bit groups into a sum. 613: x = ((x >> 1) & 0x55555555) + (x & 0x55555555); 614: x = ((x >> 2) & 0x33333333) + (x & 0x33333333); 615: x = ((x >> 4) & 0x0f0f0f0f) + (x & 0x0f0f0f0f); 616: x = ((x >> 8) & 0x00ff00ff) + (x & 0x00ff00ff); 617: return ((x >> 16) & 0x0000ffff) + (x & 0x0000ffff); 618: } 619: 620: /** 621: * Rotate x to the left by distance bits. 622: * @param x the value to rotate 623: * @param distance the number of bits by which to rotate 624: * @since 1.5 625: */ 626: public static int rotateLeft(int x, int distance) 627: { 628: // This trick works because the shift operators implicitly mask 629: // the shift count. 630: return (x << distance) | (x >>> - distance); 631: } 632: 633: /** 634: * Rotate x to the right by distance bits. 635: * @param x the value to rotate 636: * @param distance the number of bits by which to rotate 637: * @since 1.5 638: */ 639: public static int rotateRight(int x, int distance) 640: { 641: // This trick works because the shift operators implicitly mask 642: // the shift count. 643: return (x << - distance) | (x >>> distance); 644: } 645: 646: /** 647: * Find the highest set bit in value, and return a new value 648: * with only that bit set. 649: * @param value the value to examine 650: * @since 1.5 651: */ 652: public static int highestOneBit(int value) 653: { 654: value |= value >>> 1; 655: value |= value >>> 2; 656: value |= value >>> 4; 657: value |= value >>> 8; 658: value |= value >>> 16; 659: return value ^ (value >>> 1); 660: } 661: 662: /** 663: * Return the number of leading zeros in value. 664: * @param value the value to examine 665: * @since 1.5 666: */ 667: public static int numberOfLeadingZeros(int value) 668: { 669: value |= value >>> 1; 670: value |= value >>> 2; 671: value |= value >>> 4; 672: value |= value >>> 8; 673: value |= value >>> 16; 674: return bitCount(~value); 675: } 676: 677: /** 678: * Find the lowest set bit in value, and return a new value 679: * with only that bit set. 680: * @param value the value to examine 681: * @since 1.5 682: */ 683: public static int lowestOneBit(int value) 684: { 685: // Classic assembly trick. 686: return value & - value; 687: } 688: 689: /** 690: * Find the number of trailing zeros in value. 691: * @param value the value to examine 692: * @since 1.5 693: */ 694: public static int numberOfTrailingZeros(int value) 695: { 696: return bitCount((value & -value) - 1); 697: } 698: 699: /** 700: * Return 1 if x is positive, -1 if it is negative, and 0 if it is 701: * zero. 702: * @param x the value to examine 703: * @since 1.5 704: */ 705: public static int signum(int x) 706: { 707: return (x >> 31) | (-x >>> 31); 708: 709: // The LHS propagates the sign bit through every bit in the word; 710: // if X < 0, every bit is set to 1, else 0. if X > 0, the RHS 711: // negates x and shifts the resulting 1 in the sign bit to the 712: // LSB, leaving every other bit 0. 713: 714: // Hacker's Delight, Section 2-7 715: } 716: 717: /** 718: * Reverse the bytes in val. 719: * @since 1.5 720: */ 721: public static int reverseBytes(int val) 722: { 723: return ( ((val >> 24) & 0xff) 724: | ((val >> 8) & 0xff00) 725: | ((val << 8) & 0xff0000) 726: | ((val << 24) & 0xff000000)); 727: } 728: 729: /** 730: * Reverse the bits in val. 731: * @since 1.5 732: */ 733: public static int reverse(int val) 734: { 735: // Successively swap alternating bit groups. 736: val = ((val >> 1) & 0x55555555) + ((val << 1) & ~0x55555555); 737: val = ((val >> 2) & 0x33333333) + ((val << 2) & ~0x33333333); 738: val = ((val >> 4) & 0x0f0f0f0f) + ((val << 4) & ~0x0f0f0f0f); 739: val = ((val >> 8) & 0x00ff00ff) + ((val << 8) & ~0x00ff00ff); 740: return ((val >> 16) & 0x0000ffff) + ((val << 16) & ~0x0000ffff); 741: } 742: 743: /** 744: * Helper for converting unsigned numbers to String. 745: * 746: * @param num the number 747: * @param exp log2(digit) (ie. 1, 3, or 4 for binary, oct, hex) 748: */ 749: // Package visible for use by Long. 750: static String toUnsignedString(int num, int exp) 751: { 752: // Compute string length 753: int size = 1; 754: int copy = num >>> exp; 755: while (copy != 0) 756: { 757: size++; 758: copy >>>= exp; 759: } 760: // Quick path for single character strings 761: if (size == 1) 762: return new String(digits, num, 1, true); 763: 764: // Encode into buffer 765: int mask = (1 << exp) - 1; 766: char[] buffer = new char[size]; 767: int i = size; 768: do 769: { 770: buffer[--i] = digits[num & mask]; 771: num >>>= exp; 772: } 773: while (num != 0); 774: 775: // Package constructor avoids an array copy. 776: return new String(buffer, i, size - i, true); 777: } 778: 779: /** 780: * Helper for parsing ints, used by Integer, Short, and Byte. 781: * 782: * @param str the string to parse 783: * @param radix the radix to use, must be 10 if decode is true 784: * @param decode if called from decode 785: * @return the parsed int value 786: * @throws NumberFormatException if there is an error 787: * @throws NullPointerException if decode is true and str if null 788: * @see #parseInt(String, int) 789: * @see #decode(String) 790: * @see Byte#parseByte(String, int) 791: * @see Short#parseShort(String, int) 792: */ 793: static int parseInt(String str, int radix, boolean decode) 794: { 795: if (! decode && str == null) 796: throw new NumberFormatException(); 797: int index = 0; 798: int len = str.length(); 799: boolean isNeg = false; 800: if (len == 0) 801: throw new NumberFormatException("string length is null"); 802: int ch = str.charAt(index); 803: if (ch == '-') 804: { 805: if (len == 1) 806: throw new NumberFormatException("pure '-'"); 807: isNeg = true; 808: ch = str.charAt(++index); 809: } 810: else if (ch == '+') 811: { 812: if (len == 1) 813: throw new NumberFormatException("pure '+'"); 814: ch = str.charAt(++index); 815: } 816: if (decode) 817: { 818: if (ch == '0') 819: { 820: if (++index == len) 821: return 0; 822: if ((str.charAt(index) & ~('x' ^ 'X')) == 'X') 823: { 824: radix = 16; 825: index++; 826: } 827: else 828: radix = 8; 829: } 830: else if (ch == '#') 831: { 832: radix = 16; 833: index++; 834: } 835: } 836: if (index == len) 837: throw new NumberFormatException("non terminated number: " + str); 838: 839: int max = MAX_VALUE / radix; 840: // We can't directly write `max = (MAX_VALUE + 1) / radix'. 841: // So instead we fake it. 842: if (isNeg && MAX_VALUE % radix == radix - 1) 843: ++max; 844: 845: int val = 0; 846: while (index < len) 847: { 848: if (val < 0 || val > max) 849: throw new NumberFormatException("number overflow (pos=" + index + ") : " + str); 850: 851: ch = Character.digit(str.charAt(index++), radix); 852: val = val * radix + ch; 853: if (ch < 0 || (val < 0 && (! isNeg || val != MIN_VALUE))) 854: throw new NumberFormatException("invalid character at position " + index + " in " + str); 855: } 856: return isNeg ? -val : val; 857: } 858: }