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 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 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 |