src/java.base/share/classes/java/lang/Integer.java
Print this page
*** 27,36 ****
--- 27,40 ----
import java.lang.annotation.Native;
import java.util.Objects;
import jdk.internal.HotSpotIntrinsicCandidate;
+ import static java.lang.String.COMPACT_STRINGS;
+ import static java.lang.String.LATIN1;
+ import static java.lang.String.UTF16;
+
/**
* 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}.
*
*** 136,164 ****
/* 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 first argument as an
* unsigned integer value in the radix specified by the second
--- 140,190 ----
/* Use the faster version */
if (radix == 10) {
return toString(i);
}
! if (COMPACT_STRINGS) {
! byte[] buf = new byte[33];
boolean negative = (i < 0);
int charPos = 32;
if (!negative) {
i = -i;
}
while (i <= -radix) {
! buf[charPos--] = (byte)digits[-(i % radix)];
i = i / radix;
}
! buf[charPos] = (byte)digits[-i];
if (negative) {
buf[--charPos] = '-';
}
! return StringLatin1.newString(buf, charPos, (33 - charPos));
! }
! return toStringUTF16(i, radix);
! }
!
! private static String toStringUTF16(int i, int radix) {
! byte[] buf = new byte[33 * 2];
! boolean negative = (i < 0);
! int charPos = 32;
! if (!negative) {
! i = -i;
! }
! while (i <= -radix) {
! StringUTF16.putChar(buf, charPos--, digits[-(i % radix)]);
! i = i / radix;
! }
! StringUTF16.putChar(buf, charPos, digits[-i]);
!
! if (negative) {
! StringUTF16.putChar(buf, --charPos, '-');
! }
! return StringUTF16.newString(buf, charPos, (33 - charPos));
}
/**
* Returns a string representation of the first argument as an
* unsigned integer value in the radix specified by the second
*** 310,325 ****
*/
private static String toUnsignedString0(int val, int shift) {
// assert shift > 0 && shift <=5 : "Illegal shift value";
int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
- char[] buf = new char[chars];
formatUnsignedInt(val, shift, buf, 0, chars);
!
! // Use special constructor which takes over "buf".
! return new String(buf, true);
}
/**
* Format an {@code int} (treated as unsigned) into a character buffer. If
* {@code len} exceeds the formatted ASCII representation of {@code val},
--- 336,355 ----
*/
private static String toUnsignedString0(int val, int shift) {
// assert shift > 0 && shift <=5 : "Illegal shift value";
int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
+ if (COMPACT_STRINGS) {
+ byte[] buf = new byte[chars];
formatUnsignedInt(val, shift, buf, 0, chars);
! return new String(buf, LATIN1);
! } else {
! byte[] buf = new byte[chars * 2];
! formatUnsignedIntUTF16(val, shift, buf, 0, chars);
! return new String(buf, UTF16);
! }
}
/**
* Format an {@code int} (treated as unsigned) into a character buffer. If
* {@code len} exceeds the formatted ASCII representation of {@code val},
*** 342,351 ****
--- 372,403 ----
buf[--charPos] = Integer.digits[val & mask];
val >>>= shift;
} while (charPos > offset);
}
+ /** byte[]/LATIN1 version */
+ static void formatUnsignedInt(int val, int shift, byte[] buf, int offset, int len) {
+ int charPos = offset + len;
+ int radix = 1 << shift;
+ int mask = radix - 1;
+ do {
+ buf[--charPos] = (byte)Integer.digits[val & mask];
+ val >>>= shift;
+ } while (charPos > offset);
+ }
+
+ /** byte[]/UTF16 version */
+ static void formatUnsignedIntUTF16(int val, int shift, byte[] buf, int offset, int len) {
+ int charPos = offset + len;
+ int radix = 1 << shift;
+ int mask = radix - 1;
+ do {
+ StringUTF16.putChar(buf, --charPos, Integer.digits[val & mask]);
+ val >>>= shift;
+ } while (charPos > offset);
+ }
+
static final 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',
*** 399,411 ****
@HotSpotIntrinsicCandidate
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(buf, true);
}
/**
* Returns a string representation of the argument as an unsigned
* decimal value.
--- 451,469 ----
@HotSpotIntrinsicCandidate
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
! if (COMPACT_STRINGS) {
! byte[] buf = new byte[size];
getChars(i, size, buf);
! return new String(buf, LATIN1);
! } else {
! byte[] buf = new byte[size * 2];
! getCharsUTF16(i, size, buf);
! return new String(buf, UTF16);
! }
}
/**
* Returns a string representation of the argument as an unsigned
* decimal value.
*** 431,441 ****
* 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) {
--- 489,533 ----
* 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, byte[] 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] = (byte)DigitOnes[r];
! buf [--charPos] = (byte)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] = (byte)digits [r];
! i = q;
! if (i == 0) break;
! }
! if (sign != 0) {
! buf [--charPos] = (byte)sign;
! }
! }
!
! static void getCharsUTF16(int i, int index, byte[] buf) {
int q, r;
int charPos = index;
char sign = 0;
if (i < 0) {
*** 447,471 ****
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;
}
}
static final int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE };
--- 539,563 ----
while (i >= 65536) {
q = i / 100;
// really: r = i - (q * 100);
r = i - ((q << 6) + (q << 5) + (q << 2));
i = q;
! StringUTF16.putChar(buf, --charPos, DigitOnes[r]);
! StringUTF16.putChar(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) ...
! StringUTF16.putChar(buf, --charPos, Integer.digits[r]);
i = q;
if (i == 0) break;
}
if (sign != 0) {
! StringUTF16.putChar(buf, --charPos, sign);
}
}
static final int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE };