Source for java.lang.Integer

   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:  * @since 1.0
  56:  * @status updated to 1.5
  57:  */
  58: public final class Integer extends Number implements Comparable<Integer>
  59: {
  60:   /**
  61:    * Compatible with JDK 1.0.2+.
  62:    */
  63:   private static final long serialVersionUID = 1360826667806852920L;
  64: 
  65:   /**
  66:    * The minimum value an <code>int</code> can represent is -2147483648 (or
  67:    * -2<sup>31</sup>).
  68:    */
  69:   public static final int MIN_VALUE = 0x80000000;
  70: 
  71:   /**
  72:    * The maximum value an <code>int</code> can represent is 2147483647 (or
  73:    * 2<sup>31</sup> - 1).
  74:    */
  75:   public static final int MAX_VALUE = 0x7fffffff;
  76: 
  77:   /**
  78:    * The primitive type <code>int</code> is represented by this
  79:    * <code>Class</code> object.
  80:    * @since 1.1
  81:    */
  82:   public static final Class<Integer> TYPE = (Class<Integer>) VMClassLoader.getPrimitiveClass('I');
  83: 
  84:   /**
  85:    * The number of bits needed to represent an <code>int</code>.
  86:    * @since 1.5
  87:    */
  88:   public static final int SIZE = 32;
  89: 
  90:   // This caches some Integer values, and is used by boxing
  91:   // conversions via valueOf().  We must cache at least -128..127;
  92:   // these constants control how much we actually cache.
  93:   private static final int MIN_CACHE = -128;
  94:   private static final int MAX_CACHE = 127;
  95:   private static Integer[] intCache = new Integer[MAX_CACHE - MIN_CACHE + 1];
  96: 
  97:   /**
  98:    * The immutable value of this Integer.
  99:    *
 100:    * @serial the wrapped int
 101:    */
 102:   private final int value;
 103: 
 104:   /**
 105:    * Create an <code>Integer</code> object representing the value of the
 106:    * <code>int</code> argument.
 107:    *
 108:    * @param value the value to use
 109:    */
 110:   public Integer(int value)
 111:   {
 112:     this.value = value;
 113:   }
 114: 
 115:   /**
 116:    * Create an <code>Integer</code> object representing the value of the
 117:    * argument after conversion to an <code>int</code>.
 118:    *
 119:    * @param s the string to convert
 120:    * @throws NumberFormatException if the String does not contain an int
 121:    * @see #valueOf(String)
 122:    */
 123:   public Integer(String s)
 124:   {
 125:     value = parseInt(s, 10, false);
 126:   }
 127: 
 128:   /**
 129:    * Converts the <code>int</code> to a <code>String</code> using
 130:    * the specified radix (base). If the radix exceeds
 131:    * <code>Character.MIN_RADIX</code> or <code>Character.MAX_RADIX</code>, 10
 132:    * is used instead. If the result is negative, the leading character is
 133:    * '-' ('\\u002D'). The remaining characters come from
 134:    * <code>Character.forDigit(digit, radix)</code> ('0'-'9','a'-'z').
 135:    *
 136:    * @param num the <code>int</code> to convert to <code>String</code>
 137:    * @param radix the radix (base) to use in the conversion
 138:    * @return the <code>String</code> representation of the argument
 139:    */
 140:   public static String toString(int num, int radix)
 141:   {
 142:     if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
 143:       radix = 10;
 144: 
 145:     // For negative numbers, print out the absolute value w/ a leading '-'.
 146:     // Use an array large enough for a binary number.
 147:     char[] buffer = new char[33];
 148:     int i = 33;
 149:     boolean isNeg = false;
 150:     if (num < 0)
 151:       {
 152:         isNeg = true;
 153:         num = -num;
 154: 
 155:         // When the value is MIN_VALUE, it overflows when made positive
 156:         if (num < 0)
 157:       {
 158:         buffer[--i] = digits[(int) (-(num + radix) % radix)];
 159:         num = -(num / radix);
 160:       }
 161:       }
 162: 
 163:     do
 164:       {
 165:         buffer[--i] = digits[num % radix];
 166:         num /= radix;
 167:       }
 168:     while (num > 0);
 169: 
 170:     if (isNeg)
 171:       buffer[--i] = '-';
 172: 
 173:     // Package constructor avoids an array copy.
 174:     return new String(buffer, i, 33 - i, true);
 175:   }
 176: 
 177:   /**
 178:    * Converts the <code>int</code> to a <code>String</code> assuming it is
 179:    * unsigned in base 16.
 180:    *
 181:    * @param i the <code>int</code> to convert to <code>String</code>
 182:    * @return the <code>String</code> representation of the argument
 183:    */
 184:   public static String toHexString(int i)
 185:   {
 186:     return toUnsignedString(i, 4);
 187:   }
 188: 
 189:   /**
 190:    * Converts the <code>int</code> to a <code>String</code> assuming it is
 191:    * unsigned in base 8.
 192:    *
 193:    * @param i the <code>int</code> to convert to <code>String</code>
 194:    * @return the <code>String</code> representation of the argument
 195:    */
 196:   public static String toOctalString(int i)
 197:   {
 198:     return toUnsignedString(i, 3);
 199:   }
 200: 
 201:   /**
 202:    * Converts the <code>int</code> to a <code>String</code> assuming it is
 203:    * unsigned in base 2.
 204:    *
 205:    * @param i the <code>int</code> to convert to <code>String</code>
 206:    * @return the <code>String</code> representation of the argument
 207:    */
 208:   public static String toBinaryString(int i)
 209:   {
 210:     return toUnsignedString(i, 1);
 211:   }
 212: 
 213:   /**
 214:    * Converts the <code>int</code> to a <code>String</code> and assumes
 215:    * a radix of 10.
 216:    *
 217:    * @param i the <code>int</code> to convert to <code>String</code>
 218:    * @return the <code>String</code> representation of the argument
 219:    * @see #toString(int, int)
 220:    */
 221:   public static String toString(int i)
 222:   {
 223:     // This is tricky: in libgcj, String.valueOf(int) is a fast native
 224:     // implementation.  In Classpath it just calls back to
 225:     // Integer.toString(int, int).
 226:     return String.valueOf(i);
 227:   }
 228: 
 229:   /**
 230:    * Converts the specified <code>String</code> into an <code>int</code>
 231:    * using the specified radix (base). The string must not be <code>null</code>
 232:    * or empty. It may begin with an optional '-', which will negate the answer,
 233:    * provided that there are also valid digits. Each digit is parsed as if by
 234:    * <code>Character.digit(d, radix)</code>, and must be in the range
 235:    * <code>0</code> to <code>radix - 1</code>. Finally, the result must be
 236:    * within <code>MIN_VALUE</code> to <code>MAX_VALUE</code>, inclusive.
 237:    * Unlike Double.parseDouble, you may not have a leading '+'.
 238:    *
 239:    * @param str the <code>String</code> to convert
 240:    * @param radix the radix (base) to use in the conversion
 241:    * @return the <code>String</code> argument converted to <code>int</code>
 242:    * @throws NumberFormatException if <code>s</code> cannot be parsed as an
 243:    *         <code>int</code>
 244:    */
 245:   public static int parseInt(String str, int radix)
 246:   {
 247:     return parseInt(str, radix, false);
 248:   }
 249: 
 250:   /**
 251:    * Converts the specified <code>String</code> into an <code>int</code>.
 252:    * This function assumes a radix of 10.
 253:    *
 254:    * @param s the <code>String</code> to convert
 255:    * @return the <code>int</code> value of <code>s</code>
 256:    * @throws NumberFormatException if <code>s</code> cannot be parsed as an
 257:    *         <code>int</code>
 258:    * @see #parseInt(String, int)
 259:    */
 260:   public static int parseInt(String s)
 261:   {
 262:     return parseInt(s, 10, false);
 263:   }
 264: 
 265:   /**
 266:    * Creates a new <code>Integer</code> object using the <code>String</code>
 267:    * and specified radix (base).
 268:    *
 269:    * @param s the <code>String</code> to convert
 270:    * @param radix the radix (base) to convert with
 271:    * @return the new <code>Integer</code>
 272:    * @throws NumberFormatException if <code>s</code> cannot be parsed as an
 273:    *         <code>int</code>
 274:    * @see #parseInt(String, int)
 275:    */
 276:   public static Integer valueOf(String s, int radix)
 277:   {
 278:     return new Integer(parseInt(s, radix, false));
 279:   }
 280: 
 281:   /**
 282:    * Creates a new <code>Integer</code> object using the <code>String</code>,
 283:    * assuming a radix of 10.
 284:    *
 285:    * @param s the <code>String</code> to convert
 286:    * @return the new <code>Integer</code>
 287:    * @throws NumberFormatException if <code>s</code> cannot be parsed as an
 288:    *         <code>int</code>
 289:    * @see #Integer(String)
 290:    * @see #parseInt(String)
 291:    */
 292:   public static Integer valueOf(String s)
 293:   {
 294:     return new Integer(parseInt(s, 10, false));
 295:   }
 296: 
 297:   /**
 298:    * Returns an <code>Integer</code> object wrapping the value.
 299:    * In contrast to the <code>Integer</code> constructor, this method
 300:    * will cache some values.  It is used by boxing conversion.
 301:    *
 302:    * @param val the value to wrap
 303:    * @return the <code>Integer</code>
 304:    */
 305:   public static Integer valueOf(int val)
 306:   {
 307:     if (val < MIN_CACHE || val > MAX_CACHE)
 308:       return new Integer(val);
 309:     synchronized (intCache)
 310:       {
 311:     if (intCache[val - MIN_CACHE] == null)
 312:       intCache[val - MIN_CACHE] = new Integer(val);
 313:     return intCache[val - MIN_CACHE];
 314:       }
 315:   }
 316: 
 317:   /**
 318:    * Return the value of this <code>Integer</code> as a <code>byte</code>.
 319:    *
 320:    * @return the byte value
 321:    */
 322:   public byte byteValue()
 323:   {
 324:     return (byte) value;
 325:   }
 326: 
 327:   /**
 328:    * Return the value of this <code>Integer</code> as a <code>short</code>.
 329:    *
 330:    * @return the short value
 331:    */
 332:   public short shortValue()
 333:   {
 334:     return (short) value;
 335:   }
 336: 
 337:   /**
 338:    * Return the value of this <code>Integer</code>.
 339:    * @return the int value
 340:    */
 341:   public int intValue()
 342:   {
 343:     return value;
 344:   }
 345: 
 346:   /**
 347:    * Return the value of this <code>Integer</code> as a <code>long</code>.
 348:    *
 349:    * @return the long value
 350:    */
 351:   public long longValue()
 352:   {
 353:     return value;
 354:   }
 355: 
 356:   /**
 357:    * Return the value of this <code>Integer</code> as a <code>float</code>.
 358:    *
 359:    * @return the float value
 360:    */
 361:   public float floatValue()
 362:   {
 363:     return value;
 364:   }
 365: 
 366:   /**
 367:    * Return the value of this <code>Integer</code> as a <code>double</code>.
 368:    *
 369:    * @return the double value
 370:    */
 371:   public double doubleValue()
 372:   {
 373:     return value;
 374:   }
 375: 
 376:   /**
 377:    * Converts the <code>Integer</code> value to a <code>String</code> and
 378:    * assumes a radix of 10.
 379:    *
 380:    * @return the <code>String</code> representation
 381:    */
 382:   public String toString()
 383:   {
 384:     return String.valueOf(value);
 385:   }
 386: 
 387:   /**
 388:    * Return a hashcode representing this Object. <code>Integer</code>'s hash
 389:    * code is simply its value.
 390:    *
 391:    * @return this Object's hash code
 392:    */
 393:   public int hashCode()
 394:   {
 395:     return value;
 396:   }
 397: 
 398:   /**
 399:    * Returns <code>true</code> if <code>obj</code> is an instance of
 400:    * <code>Integer</code> and represents the same int value.
 401:    *
 402:    * @param obj the object to compare
 403:    * @return whether these Objects are semantically equal
 404:    */
 405:   public boolean equals(Object obj)
 406:   {
 407:     return obj instanceof Integer && value == ((Integer) obj).value;
 408:   }
 409: 
 410:   /**
 411:    * Get the specified system property as an <code>Integer</code>. The
 412:    * <code>decode()</code> method will be used to interpret the value of
 413:    * the property.
 414:    *
 415:    * @param nm the name of the system property
 416:    * @return the system property as an <code>Integer</code>, or null if the
 417:    *         property is not found or cannot be decoded
 418:    * @throws SecurityException if accessing the system property is forbidden
 419:    * @see System#getProperty(String)
 420:    * @see #decode(String)
 421:    */
 422:   public static Integer getInteger(String nm)
 423:   {
 424:     return getInteger(nm, null);
 425:   }
 426: 
 427:   /**
 428:    * Get the specified system property as an <code>Integer</code>, or use a
 429:    * default <code>int</code> value if the property is not found or is not
 430:    * decodable. The <code>decode()</code> method will be used to interpret
 431:    * the value of the property.
 432:    *
 433:    * @param nm the name of the system property
 434:    * @param val the default value
 435:    * @return the value of the system property, or the default
 436:    * @throws SecurityException if accessing the system property is forbidden
 437:    * @see System#getProperty(String)
 438:    * @see #decode(String)
 439:    */
 440:   public static Integer getInteger(String nm, int val)
 441:   {
 442:     Integer result = getInteger(nm, null);
 443:     return result == null ? new Integer(val) : result;
 444:   }
 445: 
 446:   /**
 447:    * Get the specified system property as an <code>Integer</code>, or use a
 448:    * default <code>Integer</code> value if the property is not found or is
 449:    * not decodable. The <code>decode()</code> method will be used to
 450:    * interpret the value of the property.
 451:    *
 452:    * @param nm the name of the system property
 453:    * @param def the default value
 454:    * @return the value of the system property, or the default
 455:    * @throws SecurityException if accessing the system property is forbidden
 456:    * @see System#getProperty(String)
 457:    * @see #decode(String)
 458:    */
 459:   public static Integer getInteger(String nm, Integer def)
 460:   {
 461:     if (nm == null || "".equals(nm))
 462:       return def;
 463:     nm = System.getProperty(nm);
 464:     if (nm == null)
 465:       return def;
 466:     try
 467:       {
 468:         return decode(nm);
 469:       }
 470:     catch (NumberFormatException e)
 471:       {
 472:         return def;
 473:       }
 474:   }
 475: 
 476:   /**
 477:    * Convert the specified <code>String</code> into an <code>Integer</code>.
 478:    * The <code>String</code> may represent decimal, hexadecimal, or
 479:    * octal numbers.
 480:    *
 481:    * <p>The extended BNF grammar is as follows:<br>
 482:    * <pre>
 483:    * <em>DecodableString</em>:
 484:    *      ( [ <code>-</code> ] <em>DecimalNumber</em> )
 485:    *    | ( [ <code>-</code> ] ( <code>0x</code> | <code>0X</code>
 486:    *              | <code>#</code> ) <em>HexDigit</em> { <em>HexDigit</em> } )
 487:    *    | ( [ <code>-</code> ] <code>0</code> { <em>OctalDigit</em> } )
 488:    * <em>DecimalNumber</em>:
 489:    *        <em>DecimalDigit except '0'</em> { <em>DecimalDigit</em> }
 490:    * <em>DecimalDigit</em>:
 491:    *        <em>Character.digit(d, 10) has value 0 to 9</em>
 492:    * <em>OctalDigit</em>:
 493:    *        <em>Character.digit(d, 8) has value 0 to 7</em>
 494:    * <em>DecimalDigit</em>:
 495:    *        <em>Character.digit(d, 16) has value 0 to 15</em>
 496:    * </pre>
 497:    * Finally, the value must be in the range <code>MIN_VALUE</code> to
 498:    * <code>MAX_VALUE</code>, or an exception is thrown.
 499:    *
 500:    * @param str the <code>String</code> to interpret
 501:    * @return the value of the String as an <code>Integer</code>
 502:    * @throws NumberFormatException if <code>s</code> cannot be parsed as a
 503:    *         <code>int</code>
 504:    * @throws NullPointerException if <code>s</code> is null
 505:    * @since 1.2
 506:    */
 507:   public static Integer decode(String str)
 508:   {
 509:     return new Integer(parseInt(str, 10, true));
 510:   }
 511: 
 512:   /**
 513:    * Compare two Integers numerically by comparing their <code>int</code>
 514:    * values. The result is positive if the first is greater, negative if the
 515:    * second is greater, and 0 if the two are equal.
 516:    *
 517:    * @param i the Integer to compare
 518:    * @return the comparison
 519:    * @since 1.2
 520:    */
 521:   public int compareTo(Integer i)
 522:   {
 523:     if (value == i.value)
 524:       return 0;
 525:     // Returns just -1 or 1 on inequality; doing math might overflow.
 526:     return value > i.value ? 1 : -1;
 527:   }
 528: 
 529:   /**
 530:    * Return the number of bits set in x.
 531:    * @param x value to examine
 532:    * @since 1.5
 533:    */
 534:   public static int bitCount(int x)
 535:   {
 536:     // Successively collapse alternating bit groups into a sum.
 537:     x = ((x >> 1) & 0x55555555) + (x & 0x55555555);
 538:     x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
 539:     x = ((x >> 4) & 0x0f0f0f0f) + (x & 0x0f0f0f0f);
 540:     x = ((x >> 8) & 0x00ff00ff) + (x & 0x00ff00ff);
 541:     return ((x >> 16) & 0x0000ffff) + (x & 0x0000ffff);
 542:   }
 543: 
 544:   /**
 545:    * Rotate x to the left by distance bits.
 546:    * @param x the value to rotate
 547:    * @param distance the number of bits by which to rotate
 548:    * @since 1.5
 549:    */
 550:   public static int rotateLeft(int x, int distance)
 551:   {
 552:     // This trick works because the shift operators implicitly mask
 553:     // the shift count.
 554:     return (x << distance) | (x >>> - distance);
 555:   }
 556: 
 557:   /**
 558:    * Rotate x to the right by distance bits.
 559:    * @param x the value to rotate
 560:    * @param distance the number of bits by which to rotate
 561:    * @since 1.5
 562:    */
 563:   public static int rotateRight(int x, int distance)
 564:   {
 565:     // This trick works because the shift operators implicitly mask
 566:     // the shift count.
 567:     return (x << - distance) | (x >>> distance);
 568:   }
 569: 
 570:   /**
 571:    * Find the highest set bit in value, and return a new value
 572:    * with only that bit set.
 573:    * @param value the value to examine
 574:    * @since 1.5
 575:    */
 576:   public static int highestOneBit(int value)
 577:   {
 578:     value |= value >>> 1;
 579:     value |= value >>> 2;
 580:     value |= value >>> 4;
 581:     value |= value >>> 8;
 582:     value |= value >>> 16;
 583:     return value ^ (value >>> 1);
 584:   }
 585: 
 586:   /**
 587:    * Return the number of leading zeros in value.
 588:    * @param value the value to examine
 589:    * @since 1.5
 590:    */
 591:   public static int numberOfLeadingZeros(int value)
 592:   {
 593:     value |= value >>> 1;
 594:     value |= value >>> 2;
 595:     value |= value >>> 4;
 596:     value |= value >>> 8;
 597:     value |= value >>> 16;
 598:     return bitCount(~value);
 599:   }
 600: 
 601:   /**
 602:    * Find the lowest set bit in value, and return a new value
 603:    * with only that bit set.
 604:    * @param value the value to examine
 605:    * @since 1.5
 606:    */
 607:   public static int lowestOneBit(int value)
 608:   {
 609:     // Classic assembly trick.
 610:     return value & - value;
 611:   }
 612: 
 613:   /**
 614:    * Find the number of trailing zeros in value.
 615:    * @param value the value to examine
 616:    * @since 1.5
 617:    */
 618:   public static int numberOfTrailingZeros(int value)
 619:   {
 620:     return bitCount((value & -value) - 1);
 621:   }
 622: 
 623:   /**
 624:    * Return 1 if x is positive, -1 if it is negative, and 0 if it is
 625:    * zero.
 626:    * @param x the value to examine
 627:    * @since 1.5
 628:    */
 629:   public static int signum(int x)
 630:   {
 631:     return x < 0 ? -1 : (x > 0 ? 1 : 0);
 632:   }
 633: 
 634:   /**
 635:    * Reverse the bytes in val.
 636:    * @since 1.5
 637:    */
 638:   public static int reverseBytes(int val)
 639:   {
 640:     return (  ((val >> 24) & 0xff)
 641:         | ((val >> 8) & 0xff00)
 642:         | ((val << 8) & 0xff0000)
 643:         | ((val << 24) & 0xff000000));
 644:   }
 645: 
 646:   /**
 647:    * Reverse the bits in val.
 648:    * @since 1.5
 649:    */
 650:   public static int reverse(int val)
 651:   {
 652:     // Successively swap alternating bit groups.
 653:     val = ((val >> 1) & 0x55555555) + ((val << 1) & ~0x55555555);
 654:     val = ((val >> 2) & 0x33333333) + ((val << 2) & ~0x33333333);
 655:     val = ((val >> 4) & 0x0f0f0f0f) + ((val << 4) & ~0x0f0f0f0f);
 656:     val = ((val >> 8) & 0x00ff00ff) + ((val << 8) & ~0x00ff00ff);
 657:     return ((val >> 16) & 0x0000ffff) + ((val << 16) & ~0x0000ffff);
 658:   }
 659: 
 660:   /**
 661:    * Helper for converting unsigned numbers to String.
 662:    *
 663:    * @param num the number
 664:    * @param exp log2(digit) (ie. 1, 3, or 4 for binary, oct, hex)
 665:    */
 666:   // Package visible for use by Long.
 667:   static String toUnsignedString(int num, int exp)
 668:   {
 669:     // Use an array large enough for a binary number.
 670:     int mask = (1 << exp) - 1;
 671:     char[] buffer = new char[32];
 672:     int i = 32;
 673:     do
 674:       {
 675:         buffer[--i] = digits[num & mask];
 676:         num >>>= exp;
 677:       }
 678:     while (num != 0);
 679: 
 680:     // Package constructor avoids an array copy.
 681:     return new String(buffer, i, 32 - i, true);
 682:   }
 683: 
 684:   /**
 685:    * Helper for parsing ints, used by Integer, Short, and Byte.
 686:    *
 687:    * @param str the string to parse
 688:    * @param radix the radix to use, must be 10 if decode is true
 689:    * @param decode if called from decode
 690:    * @return the parsed int value
 691:    * @throws NumberFormatException if there is an error
 692:    * @throws NullPointerException if decode is true and str if null
 693:    * @see #parseInt(String, int)
 694:    * @see #decode(String)
 695:    * @see Byte#parseByte(String, int)
 696:    * @see Short#parseShort(String, int)
 697:    */
 698:   static int parseInt(String str, int radix, boolean decode)
 699:   {
 700:     if (! decode && str == null)
 701:       throw new NumberFormatException();
 702:     int index = 0;
 703:     int len = str.length();
 704:     boolean isNeg = false;
 705:     if (len == 0)
 706:       throw new NumberFormatException("string length is null");
 707:     int ch = str.charAt(index);
 708:     if (ch == '-')
 709:       {
 710:         if (len == 1)
 711:           throw new NumberFormatException("pure '-'");
 712:         isNeg = true;
 713:         ch = str.charAt(++index);
 714:       }
 715:     if (decode)
 716:       {
 717:         if (ch == '0')
 718:           {
 719:             if (++index == len)
 720:               return 0;
 721:             if ((str.charAt(index) & ~('x' ^ 'X')) == 'X')
 722:               {
 723:                 radix = 16;
 724:                 index++;
 725:               }
 726:             else
 727:               radix = 8;
 728:           }
 729:         else if (ch == '#')
 730:           {
 731:             radix = 16;
 732:             index++;
 733:           }
 734:       }
 735:     if (index == len)
 736:       throw new NumberFormatException("non terminated number: " + str);
 737: 
 738:     int max = MAX_VALUE / radix;
 739:     // We can't directly write `max = (MAX_VALUE + 1) / radix'.
 740:     // So instead we fake it.
 741:     if (isNeg && MAX_VALUE % radix == radix - 1)
 742:       ++max;
 743: 
 744:     int val = 0;
 745:     while (index < len)
 746:       {
 747:     if (val < 0 || val > max)
 748:       throw new NumberFormatException("number overflow (pos=" + index + ") : " + str);
 749: 
 750:         ch = Character.digit(str.charAt(index++), radix);
 751:         val = val * radix + ch;
 752:         if (ch < 0 || (val < 0 && (! isNeg || val != MIN_VALUE)))
 753:           throw new NumberFormatException("invalid character at position " + index + " in " + str);
 754:       }
 755:     return isNeg ? -val : val;
 756:   }
 757: }