src/java.base/share/classes/java/lang/Long.java
Print this page
*** 28,37 ****
--- 28,40 ----
import java.lang.annotation.Native;
import java.math.*;
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 Long} class wraps a value of the primitive type {@code
* long} in an object. An object of type {@code Long} contains a
* single field whose type is {@code long}.
*** 122,150 ****
public static String toString(long i, int radix) {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
if (radix == 10)
return toString(i);
! char[] buf = new char[65];
int charPos = 64;
boolean negative = (i < 0);
if (!negative) {
i = -i;
}
while (i <= -radix) {
! buf[charPos--] = Integer.digits[(int)(-(i % radix))];
i = i / radix;
}
! buf[charPos] = Integer.digits[(int)(-i)];
if (negative) {
buf[--charPos] = '-';
}
! return new String(buf, charPos, (65 - charPos));
}
/**
* Returns a string representation of the first argument as an
* unsigned integer value in the radix specified by the second
--- 125,174 ----
public static String toString(long i, int radix) {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
if (radix == 10)
return toString(i);
!
! if (COMPACT_STRINGS) {
! byte[] buf = new byte[65];
int charPos = 64;
boolean negative = (i < 0);
if (!negative) {
i = -i;
}
while (i <= -radix) {
! buf[charPos--] = (byte)Integer.digits[(int)(-(i % radix))];
i = i / radix;
}
! buf[charPos] = (byte)Integer.digits[(int)(-i)];
if (negative) {
buf[--charPos] = '-';
}
+ return StringLatin1.newString(buf, charPos, (65 - charPos));
+ }
+ return toStringUTF16(i, radix);
+ }
! private static String toStringUTF16(long i, int radix) {
! byte[] buf = new byte[65 * 2];
! int charPos = 64;
! boolean negative = (i < 0);
! if (!negative) {
! i = -i;
! }
! while (i <= -radix) {
! StringUTF16.putChar(buf, charPos--, Integer.digits[(int)(-(i % radix))]);
! i = i / radix;
! }
! StringUTF16.putChar(buf, charPos, Integer.digits[(int)(-i)]);
! if (negative) {
! StringUTF16.putChar(buf, --charPos, '-');
! }
! return StringUTF16.newString(buf, charPos, (65 - charPos));
}
/**
* Returns a string representation of the first argument as an
* unsigned integer value in the radix specified by the second
*** 353,366 ****
*/
static String toUnsignedString0(long val, int shift) {
// assert shift > 0 && shift <=5 : "Illegal shift value";
int mag = Long.SIZE - Long.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
- char[] buf = new char[chars];
! formatUnsignedLong(val, shift, buf, 0, chars);
! return new String(buf, true);
}
/**
* Format a long (treated as unsigned) into a character buffer. If
* {@code len} exceeds the formatted ASCII representation of {@code val},
--- 377,396 ----
*/
static String toUnsignedString0(long val, int shift) {
// assert shift > 0 && shift <=5 : "Illegal shift value";
int mag = Long.SIZE - Long.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
! if (COMPACT_STRINGS) {
! byte[] buf = new byte[chars];
! formatUnsignedLong0(val, shift, buf, 0, chars);
! return new String(buf, LATIN1);
! } else {
! byte[] buf = new byte[chars * 2];
! formatUnsignedLong0UTF16(val, shift, buf, 0, chars);
! return new String(buf, UTF16);
! }
}
/**
* Format a long (treated as unsigned) into a character buffer. If
* {@code len} exceeds the formatted ASCII representation of {@code val},
*** 383,392 ****
--- 413,444 ----
buf[--charPos] = Integer.digits[((int) val) & mask];
val >>>= shift;
} while (charPos > offset);
}
+ /** byte[]/LATIN1 version */
+ static void formatUnsignedLong0(long 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[((int) val) & mask];
+ val >>>= shift;
+ } while (charPos > offset);
+ }
+
+ /** byte[]/UTF16 version */
+ static void formatUnsignedLong0UTF16(long 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[((int) val) & mask]);
+ val >>>= shift;
+ } while (charPos > offset);
+ }
+
/**
* Returns a {@code String} object representing the specified
* {@code long}. The argument is converted to signed decimal
* representation and returned as a string, exactly as if the
* argument and the radix 10 were given as arguments to the {@link
*** 397,409 ****
*/
public static String toString(long i) {
if (i == Long.MIN_VALUE)
return "-9223372036854775808";
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.
--- 449,467 ----
*/
public static String toString(long i) {
if (i == Long.MIN_VALUE)
return "-9223372036854775808";
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.
*** 429,439 ****
* digit at the specified index (exclusive), and working
* backwards from there.
*
* Will fail if i == Long.MIN_VALUE
*/
! static void getChars(long i, int index, char[] buf) {
long q;
int r;
int charPos = index;
char sign = 0;
--- 487,544 ----
* digit at the specified index (exclusive), and working
* backwards from there.
*
* Will fail if i == Long.MIN_VALUE
*/
! static void getChars(long i, int index, byte[] buf) {
! long q;
! int r;
! int charPos = index;
! char sign = 0;
!
! if (i < 0) {
! sign = '-';
! i = -i;
! }
!
! // Get 2 digits/iteration using longs until quotient fits into an int
! while (i > Integer.MAX_VALUE) {
! q = i / 100;
! // really: r = i - (q * 100);
! r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
! i = q;
! buf[--charPos] = (byte)Integer.DigitOnes[r];
! buf[--charPos] = (byte)Integer.DigitTens[r];
! }
!
! // Get 2 digits/iteration using ints
! int q2;
! int i2 = (int)i;
! while (i2 >= 65536) {
! q2 = i2 / 100;
! // really: r = i2 - (q * 100);
! r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
! i2 = q2;
! buf[--charPos] = (byte)Integer.DigitOnes[r];
! buf[--charPos] = (byte)Integer.DigitTens[r];
! }
!
! // Fall thru to fast mode for smaller numbers
! // assert(i2 <= 65536, i2);
! for (;;) {
! q2 = (i2 * 52429) >>> (16+3);
! r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ...
! buf[--charPos] = (byte)Integer.digits[r];
! i2 = q2;
! if (i2 == 0) break;
! }
! if (sign != 0) {
! buf[--charPos] = (byte)sign;
! }
! }
!
! static void getCharsUTF16(long i, int index, byte[] buf) {
long q;
int r;
int charPos = index;
char sign = 0;
*** 446,482 ****
while (i > Integer.MAX_VALUE) {
q = i / 100;
// really: r = i - (q * 100);
r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
i = q;
! buf[--charPos] = Integer.DigitOnes[r];
! buf[--charPos] = Integer.DigitTens[r];
}
// Get 2 digits/iteration using ints
int q2;
int i2 = (int)i;
while (i2 >= 65536) {
q2 = i2 / 100;
// really: r = i2 - (q * 100);
r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
i2 = q2;
! buf[--charPos] = Integer.DigitOnes[r];
! buf[--charPos] = Integer.DigitTens[r];
}
// Fall thru to fast mode for smaller numbers
// assert(i2 <= 65536, i2);
for (;;) {
q2 = (i2 * 52429) >>> (16+3);
r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ...
! buf[--charPos] = Integer.digits[r];
i2 = q2;
if (i2 == 0) break;
}
if (sign != 0) {
! buf[--charPos] = sign;
}
}
// Requires positive x
static int stringSize(long x) {
--- 551,587 ----
while (i > Integer.MAX_VALUE) {
q = i / 100;
// really: r = i - (q * 100);
r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
i = q;
! StringUTF16.putChar(buf, --charPos, Integer.DigitOnes[r]);
! StringUTF16.putChar(buf, --charPos, Integer.DigitTens[r]);
}
// Get 2 digits/iteration using ints
int q2;
int i2 = (int)i;
while (i2 >= 65536) {
q2 = i2 / 100;
// really: r = i2 - (q * 100);
r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
i2 = q2;
! StringUTF16.putChar(buf, --charPos, Integer.DigitOnes[r]);
! StringUTF16.putChar(buf, --charPos, Integer.DigitTens[r]);
}
// Fall thru to fast mode for smaller numbers
// assert(i2 <= 65536, i2);
for (;;) {
q2 = (i2 * 52429) >>> (16+3);
r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ...
! StringUTF16.putChar(buf, --charPos, Integer.digits[r]);
i2 = q2;
if (i2 == 0) break;
}
if (sign != 0) {
! StringUTF16.putChar(buf, --charPos, sign);
}
}
// Requires positive x
static int stringSize(long x) {