< prev index next >

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

Print this page




 379         int charPos = offset + len;
 380         int radix = 1 << shift;
 381         int mask = radix - 1;
 382         do {
 383             buf[--charPos] = (byte)Integer.digits[val & mask];
 384             val >>>= shift;
 385         } while (charPos > offset);
 386     }
 387 
 388     /** byte[]/UTF16 version    */
 389     static void formatUnsignedIntUTF16(int val, int shift, byte[] buf, int offset, int len) {
 390         int charPos = offset + len;
 391         int radix = 1 << shift;
 392         int mask = radix - 1;
 393         do {
 394             StringUTF16.putChar(buf, --charPos, Integer.digits[val & mask]);
 395             val >>>= shift;
 396         } while (charPos > offset);
 397     }
 398 
 399     static final char [] DigitTens = {
 400         '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
 401         '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
 402         '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
 403         '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
 404         '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
 405         '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
 406         '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
 407         '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
 408         '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
 409         '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
 410         } ;
 411 
 412     static final char [] DigitOnes = {
 413         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 414         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 415         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 416         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 417         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 418         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 419         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 420         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 421         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 422         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 423         } ;
 424 
 425         // I use the "invariant division by multiplication" trick to
 426         // accelerate Integer.toString.  In particular we want to
 427         // avoid division by 10.
 428         //
 429         // The "trick" has roughly the same performance characteristics
 430         // as the "classic" Integer.toString code on a non-JIT VM.
 431         // The trick avoids .rem and .div calls but has a longer code
 432         // path and is thus dominated by dispatch overhead.  In the
 433         // JIT case the dispatch overhead doesn't exist and the
 434         // "trick" is considerably faster than the classic code.
 435         //
 436         // RE:  Division by Invariant Integers using Multiplication
 437         //      T Gralund, P Montgomery
 438         //      ACM PLDI 1994
 439         //
 440 
 441     /**
 442      * Returns a {@code String} object representing the
 443      * specified integer. The argument is converted to signed decimal
 444      * representation and returned as a string, exactly as if the
 445      * argument and radix 10 were given as arguments to the {@link
 446      * #toString(int, int)} method.
 447      *
 448      * @param   i   an integer to be converted.
 449      * @return  a string representation of the argument in base&nbsp;10.
 450      */
 451     @HotSpotIntrinsicCandidate
 452     public static String toString(int i) {
 453         if (i == Integer.MIN_VALUE)
 454             return "-2147483648";
 455         int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
 456         if (COMPACT_STRINGS) {
 457             byte[] buf = new byte[size];
 458             getChars(i, size, buf);
 459             return new String(buf, LATIN1);
 460         } else {
 461             byte[] buf = new byte[size * 2];
 462             getCharsUTF16(i, size, buf);
 463             return new String(buf, UTF16);
 464         }
 465     }
 466 
 467     /**
 468      * Returns a string representation of the argument as an unsigned
 469      * decimal value.
 470      *
 471      * The argument is converted to unsigned decimal representation
 472      * and returned as a string exactly as if the argument and radix
 473      * 10 were given as arguments to the {@link #toUnsignedString(int,
 474      * int)} method.
 475      *


 477      * @return  an unsigned string representation of the argument.
 478      * @see     #toUnsignedString(int, int)
 479      * @since 1.8
 480      */
 481     public static String toUnsignedString(int i) {
 482         return Long.toString(toUnsignedLong(i));
 483     }
 484 
 485     /**
 486      * Places characters representing the integer i into the
 487      * character array buf. The characters are placed into
 488      * the buffer backwards starting with the least significant
 489      * digit at the specified index (exclusive), and working
 490      * backwards from there.
 491      *
 492      * Will fail if i == Integer.MIN_VALUE
 493      */
 494     static void getChars(int i, int index, byte[] buf) {
 495         int q, r;
 496         int charPos = index;
 497         char sign = 0;
 498 
 499         if (i < 0) {
 500             sign = '-';
 501             i = -i;
 502         }
 503 
 504         // Generate two digits per iteration
 505         while (i >= 65536) {
 506             q = i / 100;
 507         // really: r = i - (q * 100);
 508             r = i - ((q << 6) + (q << 5) + (q << 2));
 509             i = q;
 510             buf [--charPos] = (byte)DigitOnes[r];
 511             buf [--charPos] = (byte)DigitTens[r];
 512         }
 513 
 514         // Fall thru to fast mode for smaller numbers
 515         // assert(i <= 65536, i);
 516         for (;;) {
 517             q = (i * 52429) >>> (16+3);
 518             r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
 519             buf [--charPos] = (byte)digits [r];
 520             i = q;
 521             if (i == 0) break;
 522         }
 523         if (sign != 0) {
 524             buf [--charPos] = (byte)sign;

 525         }
 526     }
 527 
 528     static void getCharsUTF16(int i, int index, byte[] buf) {
 529         int q, r;
 530         int charPos = index;
 531         char sign = 0;
 532 
 533         if (i < 0) {
 534             sign = '-';
 535             i = -i;
 536         }
 537 
 538         // Generate two digits per iteration
 539         while (i >= 65536) {
 540             q = i / 100;
 541         // really: r = i - (q * 100);
 542             r = i - ((q << 6) + (q << 5) + (q << 2));
 543             i = q;
 544             StringUTF16.putChar(buf, --charPos, DigitOnes[r]);
 545             StringUTF16.putChar(buf, --charPos, DigitTens[r]);
 546         }
 547 
 548         // Fall thru to fast mode for smaller numbers
 549         // assert(i <= 65536, i);
 550         for (;;) {
 551             q = (i * 52429) >>> (16+3);
 552             r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
 553             StringUTF16.putChar(buf, --charPos, Integer.digits[r]);
 554             i = q;
 555             if (i == 0) break;
 556         }
 557         if (sign != 0) {
 558             StringUTF16.putChar(buf, --charPos, sign);

 559         }
 560     }
 561 
 562     static final int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
 563                                       99999999, 999999999, Integer.MAX_VALUE };
 564 
 565     // Requires positive x








 566     static int stringSize(int x) {
 567         for (int i=0; ; i++)
 568             if (x <= sizeTable[i])
 569                 return i+1;









 570     }
 571 
 572     /**
 573      * Parses the string argument as a signed integer in the radix
 574      * specified by the second argument. The characters in the string
 575      * must all be digits of the specified radix (as determined by
 576      * whether {@link java.lang.Character#digit(char, int)} returns a
 577      * nonnegative value), except that the first character may be an
 578      * ASCII minus sign {@code '-'} ({@code '\u005Cu002D'}) to
 579      * indicate a negative value or an ASCII plus sign {@code '+'}
 580      * ({@code '\u005Cu002B'}) to indicate a positive value. The
 581      * resulting integer value is returned.
 582      *
 583      * <p>An exception of type {@code NumberFormatException} is
 584      * thrown if any of the following situations occurs:
 585      * <ul>
 586      * <li>The first argument is {@code null} or is a string of
 587      * length zero.
 588      *
 589      * <li>The radix is either smaller than




 379         int charPos = offset + len;
 380         int radix = 1 << shift;
 381         int mask = radix - 1;
 382         do {
 383             buf[--charPos] = (byte)Integer.digits[val & mask];
 384             val >>>= shift;
 385         } while (charPos > offset);
 386     }
 387 
 388     /** byte[]/UTF16 version    */
 389     static void formatUnsignedIntUTF16(int val, int shift, byte[] buf, int offset, int len) {
 390         int charPos = offset + len;
 391         int radix = 1 << shift;
 392         int mask = radix - 1;
 393         do {
 394             StringUTF16.putChar(buf, --charPos, Integer.digits[val & mask]);
 395             val >>>= shift;
 396         } while (charPos > offset);
 397     }
 398 
 399     static final byte[] DigitTens = {
 400         '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
 401         '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
 402         '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
 403         '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
 404         '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
 405         '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
 406         '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
 407         '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
 408         '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
 409         '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
 410         } ;
 411 
 412     static final byte[] DigitOnes = {
 413         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 414         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 415         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 416         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 417         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 418         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 419         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 420         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 421         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 422         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 423         } ;
 424 















 425 
 426     /**
 427      * Returns a {@code String} object representing the
 428      * specified integer. The argument is converted to signed decimal
 429      * representation and returned as a string, exactly as if the
 430      * argument and radix 10 were given as arguments to the {@link
 431      * #toString(int, int)} method.
 432      *
 433      * @param   i   an integer to be converted.
 434      * @return  a string representation of the argument in base&nbsp;10.
 435      */
 436     @HotSpotIntrinsicCandidate
 437     public static String toString(int i) {
 438         if (i == Integer.MIN_VALUE)
 439             return "-2147483648";
 440         int size = stringSize(i);
 441         if (COMPACT_STRINGS) {
 442             byte[] buf = new byte[size];
 443             getChars(i, size, buf);
 444             return new String(buf, LATIN1);
 445         } else {
 446             byte[] buf = new byte[size * 2];
 447             getCharsUTF16(i, size, buf);
 448             return new String(buf, UTF16);
 449         }
 450     }
 451 
 452     /**
 453      * Returns a string representation of the argument as an unsigned
 454      * decimal value.
 455      *
 456      * The argument is converted to unsigned decimal representation
 457      * and returned as a string exactly as if the argument and radix
 458      * 10 were given as arguments to the {@link #toUnsignedString(int,
 459      * int)} method.
 460      *


 462      * @return  an unsigned string representation of the argument.
 463      * @see     #toUnsignedString(int, int)
 464      * @since 1.8
 465      */
 466     public static String toUnsignedString(int i) {
 467         return Long.toString(toUnsignedLong(i));
 468     }
 469 
 470     /**
 471      * Places characters representing the integer i into the
 472      * character array buf. The characters are placed into
 473      * the buffer backwards starting with the least significant
 474      * digit at the specified index (exclusive), and working
 475      * backwards from there.
 476      *
 477      * Will fail if i == Integer.MIN_VALUE
 478      */
 479     static void getChars(int i, int index, byte[] buf) {
 480         int q, r;
 481         int charPos = index;

 482 
 483         boolean neg = i < 0;
 484         if (neg) {
 485             i = -i;
 486         }
 487 
 488         // Generate two digits per iteration
 489         while (i >= 100) {
 490             q = i / 100;
 491             r = i - (q * 100);

 492             i = q;
 493             buf[--charPos] = DigitOnes[r];
 494             buf[--charPos] = DigitTens[r];
 495         }
 496 
 497         // We know there are at most two digits left at this point.
 498         q = i / 10;
 499         r = i - (q * 10);
 500         buf[--charPos] = (byte)(48 + r); // 48 is ASCII '0'
 501 
 502         // Whatever left is the remaining digit.
 503         if (q > 0) {
 504             buf[--charPos] = (byte)(48 + q); // 48 is ASCII '0'
 505         }
 506 
 507         if (neg) {
 508             buf[--charPos] = (byte)'-';
 509         }
 510     }
 511 
 512     static void getCharsUTF16(int i, int index, byte[] buf) {
 513         int q, r;
 514         int charPos = index;

 515 
 516         boolean neg = (i < 0);
 517         if (neg) {
 518             i = -i;
 519         }
 520 
 521         // Get 2 digits/iteration using ints
 522         while (i >= 100) {
 523             q = i / 100;
 524             r = i - (q * 100);

 525             i = q;
 526             StringUTF16.putChar(buf, --charPos, DigitOnes[r]);
 527             StringUTF16.putChar(buf, --charPos, DigitTens[r]);
 528         }
 529 
 530         // We know there are at most two digits left at this point.
 531         q = i / 10;
 532         r = i - (q * 10);
 533         StringUTF16.putChar(buf, --charPos, '0' + r);
 534 
 535         // Whatever left is the remaining digit.
 536         if (q > 0) {
 537             StringUTF16.putChar(buf, --charPos, '0' + q);
 538         }
 539 
 540         if (neg) {
 541             StringUTF16.putChar(buf, --charPos, '-');
 542         }
 543     }
 544 
 545     /**
 546      * Returns the string representation size for a given int value.
 547      * This will fail for Integer.MIN_VALUE.
 548      *
 549      * @param x int value
 550      * @return string size
 551      *
 552      * @implNote There are other ways to compute this: e.g. binary search,
 553      * but values are biased heavily towards zero, and therefore linear search
 554      * wins. The iteration results are also routinely inlined in the generated
 555      * code after loop unrolling.
 556      */
 557     static int stringSize(int x) {
 558         int d = 0;
 559         if (x < 0) {
 560             d = 1;
 561             x = -x;
 562         }
 563         int p = 10;
 564         for (int i = 1; i < 10; i++) {
 565             if (x < p)
 566                 return i + d;
 567             p = 10 * p;
 568         }
 569         return 10 + d;
 570     }
 571 
 572     /**
 573      * Parses the string argument as a signed integer in the radix
 574      * specified by the second argument. The characters in the string
 575      * must all be digits of the specified radix (as determined by
 576      * whether {@link java.lang.Character#digit(char, int)} returns a
 577      * nonnegative value), except that the first character may be an
 578      * ASCII minus sign {@code '-'} ({@code '\u005Cu002D'}) to
 579      * indicate a negative value or an ASCII plus sign {@code '+'}
 580      * ({@code '\u005Cu002B'}) to indicate a positive value. The
 581      * resulting integer value is returned.
 582      *
 583      * <p>An exception of type {@code NumberFormatException} is
 584      * thrown if any of the following situations occurs:
 585      * <ul>
 586      * <li>The first argument is {@code null} or is a string of
 587      * length zero.
 588      *
 589      * <li>The radix is either smaller than


< prev index next >