Simplifies Long.toString.
It should slightly improve the performance as well.
Adapted from the algorithm in android-sdk.
Change-Id: I10a896c52c625be4a147b0dc0e6ecad3ab8353a9
Review-Link: https://gwt-review.googlesource.com/#/c/13443/
diff --git a/user/super/com/google/gwt/emul/java/lang/Long.java b/user/super/com/google/gwt/emul/java/lang/Long.java
index ec8c799..e6313d5 100644
--- a/user/super/com/google/gwt/emul/java/lang/Long.java
+++ b/user/super/com/google/gwt/emul/java/lang/Long.java
@@ -162,36 +162,42 @@
}
public static String toString(long value, int intRadix) {
- if (intRadix == 10 || intRadix < Character.MIN_RADIX
- || intRadix > Character.MAX_RADIX) {
+ if (intRadix == 10 || intRadix < Character.MIN_RADIX || intRadix > Character.MAX_RADIX) {
return String.valueOf(value);
}
- if (Integer.MIN_VALUE <= value && value <= Integer.MAX_VALUE) {
- return Integer.toString((int) value, intRadix);
+ int intValue = (int) value;
+ if (intValue == value) {
+ return Integer.toString(intValue, intRadix);
}
- final int bufSize = 65;
- char[] buf = new char[bufSize];
- int pos = bufSize - 1;
- // Cache a converted version for performance (pure long ops are faster).
- long radix = intRadix;
- if (value >= 0) {
- while (value >= radix) {
- buf[pos--] = Character.forDigit((int) (value % radix));
- value /= radix;
- }
- buf[pos] = Character.forDigit((int) value);
- } else {
- long negRadix = -radix;
- while (value <= negRadix) {
- buf[pos--] = Character.forDigit(-((int) (value % radix)));
- value /= radix;
- }
- buf[pos--] = Character.forDigit(-((int) value));
- buf[pos] = '-';
+ /*
+ * If v is positive, negate it. This is the opposite of what one might expect. It is necessary
+ * because the range of the negative values is strictly larger than that of the positive values:
+ * there is no positive value corresponding to Long.MIN_VALUE.
+ */
+ boolean negative = value < 0;
+ if (!negative) {
+ value = -value;
}
- return String.valueOf(buf, pos, bufSize - pos);
+
+ int bufLen = intRadix < 8 ? 65 : 23; // Max chars in result (conservative)
+ char[] buf = new char[bufLen];
+ int cursor = bufLen;
+
+ // Convert radix to long before hand to avoid costly conversion on each iteration.
+ long radix = intRadix;
+ do {
+ long q = value / radix;
+ buf[--cursor] = Character.forDigit((int) (radix * q - value));
+ value = q;
+ } while (value != 0);
+
+ if (negative) {
+ buf[--cursor] = '-';
+ }
+
+ return String.valueOf(buf, cursor, bufLen - cursor);
}
public static Long valueOf(long i) {
diff --git a/user/test/com/google/gwt/emultest/java/lang/LongTest.java b/user/test/com/google/gwt/emultest/java/lang/LongTest.java
index 2710139..df38a56 100644
--- a/user/test/com/google/gwt/emultest/java/lang/LongTest.java
+++ b/user/test/com/google/gwt/emultest/java/lang/LongTest.java
@@ -281,6 +281,7 @@
assertEquals("9223372036854775807", Long.toString(Long.MAX_VALUE));
assertEquals("100000000", Long.toString(100000000L, 10));
+ assertEquals("575360400", Long.toString(100000000L, 8));
assertEquals("77777777777", Long.toString(8589934591L, 8));
assertEquals("fffffffff", Long.toString(68719476735L, 16));
assertEquals("1111111111111111111111111111111111111111111", Long.toString(8796093022207L, 2));