1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package java.lang; 18 19 /** 20 * Converts integral types to strings. This class is public but hidden so that it can also be 21 * used by java.util.Formatter to speed up %d. This class is in java.lang so that it can take 22 * advantage of the package-private String constructor. 23 * 24 * The most important methods are appendInt/appendLong and intToString(int)/longToString(int). 25 * The former are used in the implementation of StringBuilder, StringBuffer, and Formatter, while 26 * the latter are used by Integer.toString and Long.toString. 27 * 28 * The append methods take AbstractStringBuilder rather than Appendable because the latter requires 29 * CharSequences, while we only have raw char[]s. Since much of the savings come from not creating 30 * any garbage, we can't afford temporary CharSequence instances. 31 * 32 * One day the performance advantage of the binary/hex/octal specializations will be small enough 33 * that we can lose the duplication, but until then this class offers the full set. 34 * 35 * @hide 36 */ 37 public final class IntegralToString { 38 /** 39 * When appending to an AbstractStringBuilder, this thread-local char[] lets us avoid 40 * allocation of a temporary array. (We can't write straight into the AbstractStringBuilder 41 * because it's almost as expensive to work out the exact length of the result as it is to 42 * do the formatting. We could try being conservative and "delete"-ing the unused space 43 * afterwards, but then we'd need to duplicate convertInt and convertLong rather than share 44 * the code.) 45 */ 46 private static final ThreadLocal<char[]> BUFFER = new ThreadLocal<char[]>() { 47 @Override protected char[] initialValue() { 48 return new char[20]; // Maximum length of a base-10 long. 49 } 50 }; 51 52 /** 53 * These tables are used to special-case toString computation for 54 * small values. This serves three purposes: it reduces memory usage; 55 * it increases performance for small values; and it decreases the 56 * number of comparisons required to do the length computation. 57 * Elements of this table are lazily initialized on first use. 58 * No locking is necessary, i.e., we use the non-volatile, racy 59 * single-check idiom. 60 */ 61 private static final String[] SMALL_NONNEGATIVE_VALUES = new String[100]; 62 private static final String[] SMALL_NEGATIVE_VALUES = new String[100]; 63 64 /** TENS[i] contains the tens digit of the number i, 0 <= i <= 99. */ 65 private static final char[] TENS = { 66 '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 67 '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', 68 '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', 69 '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', 70 '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', 71 '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', 72 '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', 73 '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', 74 '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', 75 '9', '9', '9', '9', '9', '9', '9', '9', '9', '9' 76 }; 77 78 /** Ones [i] contains the tens digit of the number i, 0 <= i <= 99. */ 79 private static final char[] ONES = { 80 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 81 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 82 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 83 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 84 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 85 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 86 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 87 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 88 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 89 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 90 }; 91 92 /** 93 * Table for MOD / DIV 10 computation described in Section 10-21 94 * of Hank Warren's "Hacker's Delight" online addendum. 95 * http://www.hackersdelight.org/divcMore.pdf 96 */ 97 private static final char[] MOD_10_TABLE = { 98 0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 0 99 }; 100 101 /** 102 * The digits for every supported radix. 103 */ 104 private static final char[] DIGITS = { 105 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 106 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 107 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 108 'u', 'v', 'w', 'x', 'y', 'z' 109 }; 110 111 private IntegralToString() { 112 } 113 114 /** 115 * Equivalent to Integer.toString(i, radix). 116 */ 117 public static String intToString(int i, int radix) { 118 if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) { 119 radix = 10; 120 } 121 if (radix == 10) { 122 return intToString(i); 123 } 124 125 /* 126 * If i is positive, negate it. This is the opposite of what one might 127 * expect. It is necessary because the range of the negative values is 128 * strictly larger than that of the positive values: there is no 129 * positive value corresponding to Integer.MIN_VALUE. 130 */ 131 boolean negative = false; 132 if (i < 0) { 133 negative = true; 134 } else { 135 i = -i; 136 } 137 138 int bufLen = radix < 8 ? 33 : 12; // Max chars in result (conservative) 139 char[] buf = new char[bufLen]; 140 int cursor = bufLen; 141 142 do { 143 int q = i / radix; 144 buf[--cursor] = DIGITS[radix * q - i]; 145 i = q; 146 } while (i != 0); 147 148 if (negative) { 149 buf[--cursor] = '-'; 150 } 151 152 return new String(cursor, bufLen - cursor, buf); 153 } 154 155 /** 156 * Equivalent to Integer.toString(i). 157 */ 158 public static String intToString(int i) { 159 return convertInt(null, i); 160 } 161 162 /** 163 * Equivalent to sb.append(Integer.toString(i)). 164 */ 165 public static void appendInt(AbstractStringBuilder sb, int i) { 166 convertInt(sb, i); 167 } 168 169 /** 170 * Returns the string representation of i and leaves sb alone if sb is null. 171 * Returns null and appends the string representation of i to sb if sb is non-null. 172 */ 173 private static String convertInt(AbstractStringBuilder sb, int i) { 174 boolean negative = false; 175 String quickResult = null; 176 if (i < 0) { 177 negative = true; 178 i = -i; 179 if (i < 100) { 180 if (i < 0) { 181 // If -n is still negative, n is Integer.MIN_VALUE 182 quickResult = "-2147483648"; 183 } else { 184 String result = SMALL_NEGATIVE_VALUES[i]; 185 if (result == null) { 186 SMALL_NEGATIVE_VALUES[i] = result = 187 i < 10 ? stringOf('-', ONES[i]) : stringOf('-', TENS[i], ONES[i]); 188 } 189 } 190 } 191 } else { 192 if (i < 100) { 193 quickResult = SMALL_NONNEGATIVE_VALUES[i]; 194 if (quickResult == null) { 195 SMALL_NONNEGATIVE_VALUES[i] = quickResult = 196 i < 10 ? stringOf(ONES[i]) : stringOf(TENS[i], ONES[i]); 197 } 198 } 199 } 200 if (quickResult != null) { 201 if (sb != null) { 202 sb.append0(quickResult); 203 return null; 204 } 205 return quickResult; 206 } 207 208 int bufLen = 11; // Max number of chars in result 209 char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen]; 210 int cursor = bufLen; 211 212 // Calculate digits two-at-a-time till remaining digits fit in 16 bits 213 while (i >= (1 << 16)) { 214 // Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8 215 int q = (int) ((0x51EB851FL * i) >>> 37); 216 int r = i - 100*q; 217 buf[--cursor] = ONES[r]; 218 buf[--cursor] = TENS[r]; 219 i = q; 220 } 221 222 // Calculate remaining digits one-at-a-time for performance 223 while (i != 0) { 224 // Compute q = n/10 and r = n % 10 as per "Hacker's Delight" 10-8 225 int q = (0xCCCD * i) >>> 19; 226 int r = i - 10*q; 227 buf[--cursor] = DIGITS[r]; 228 i = q; 229 } 230 231 if (negative) { 232 buf[--cursor] = '-'; 233 } 234 235 if (sb != null) { 236 sb.append0(buf, cursor, bufLen - cursor); 237 return null; 238 } else { 239 return new String(cursor, bufLen - cursor, buf); 240 } 241 } 242 243 /** 244 * Equivalent to Long.toString(v, radix). 245 */ 246 public static String longToString(long v, int radix) { 247 int i = (int) v; 248 if (i == v) { 249 return intToString(i, radix); 250 } 251 252 if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) { 253 radix = 10; 254 } 255 if (radix == 10) { 256 return longToString(v); 257 } 258 259 /* 260 * If v is positive, negate it. This is the opposite of what one might 261 * expect. It is necessary because the range of the negative values is 262 * strictly larger than that of the positive values: there is no 263 * positive value corresponding to Integer.MIN_VALUE. 264 */ 265 boolean negative = false; 266 if (v < 0) { 267 negative = true; 268 } else { 269 v = -v; 270 } 271 272 int bufLen = radix < 8 ? 65 : 23; // Max chars in result (conservative) 273 char[] buf = new char[bufLen]; 274 int cursor = bufLen; 275 276 do { 277 long q = v / radix; 278 buf[--cursor] = DIGITS[(int) (radix * q - v)]; 279 v = q; 280 } while (v != 0); 281 282 if (negative) { 283 buf[--cursor] = '-'; 284 } 285 286 return new String(cursor, bufLen - cursor, buf); 287 } 288 289 /** 290 * Equivalent to Long.toString(l). 291 */ 292 public static String longToString(long l) { 293 return convertLong(null, l); 294 } 295 296 /** 297 * Equivalent to sb.append(Long.toString(l)). 298 */ 299 public static void appendLong(AbstractStringBuilder sb, long l) { 300 convertLong(sb, l); 301 } 302 303 /** 304 * Returns the string representation of n and leaves sb alone if sb is null. 305 * Returns null and appends the string representation of n to sb if sb is non-null. 306 */ 307 private static String convertLong(AbstractStringBuilder sb, long n) { 308 int i = (int) n; 309 if (i == n) { 310 return convertInt(sb, i); 311 } 312 313 boolean negative = (n < 0); 314 if (negative) { 315 n = -n; 316 if (n < 0) { 317 // If -n is still negative, n is Long.MIN_VALUE 318 String quickResult = "-9223372036854775808"; 319 if (sb != null) { 320 sb.append0(quickResult); 321 return null; 322 } 323 return quickResult; 324 } 325 } 326 327 int bufLen = 20; // Maximum number of chars in result 328 char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen]; 329 330 int low = (int) (n % 1000000000); // Extract low-order 9 digits 331 int cursor = intIntoCharArray(buf, bufLen, low); 332 333 // Zero-pad Low order part to 9 digits 334 while (cursor != (bufLen - 9)) { 335 buf[--cursor] = '0'; 336 } 337 338 /* 339 * The remaining digits are (n - low) / 1,000,000,000. This 340 * "exact division" is done as per the online addendum to Hank Warren's 341 * "Hacker's Delight" 10-20, http://www.hackersdelight.org/divcMore.pdf 342 */ 343 n = ((n - low) >>> 9) * 0x8E47CE423A2E9C6DL; 344 345 /* 346 * If the remaining digits fit in an int, emit them using a 347 * single call to intIntoCharArray. Otherwise, strip off the 348 * low-order digit, put it in buf, and then call intIntoCharArray 349 * on the remaining digits (which now fit in an int). 350 */ 351 if ((n & (-1L << 32)) == 0) { 352 cursor = intIntoCharArray(buf, cursor, (int) n); 353 } else { 354 /* 355 * Set midDigit to n % 10 356 */ 357 int lo32 = (int) n; 358 int hi32 = (int) (n >>> 32); 359 360 // midDigit = ((unsigned) low32) % 10, per "Hacker's Delight" 10-21 361 int midDigit = MOD_10_TABLE[(0x19999999 * lo32 + (lo32 >>> 1) + (lo32 >>> 3)) >>> 28]; 362 363 // Adjust midDigit for hi32. (assert hi32 == 1 || hi32 == 2) 364 midDigit -= hi32 << 2; // 1L << 32 == -4 MOD 10 365 if (midDigit < 0) { 366 midDigit += 10; 367 } 368 buf[--cursor] = DIGITS[midDigit]; 369 370 // Exact division as per Warren 10-20 371 int rest = ((int) ((n - midDigit) >>> 1)) * 0xCCCCCCCD; 372 cursor = intIntoCharArray(buf, cursor, rest); 373 } 374 375 if (negative) { 376 buf[--cursor] = '-'; 377 } 378 if (sb != null) { 379 sb.append0(buf, cursor, bufLen - cursor); 380 return null; 381 } else { 382 return new String(cursor, bufLen - cursor, buf); 383 } 384 } 385 386 /** 387 * Inserts the unsigned decimal integer represented by n into the specified 388 * character array starting at position cursor. Returns the index after 389 * the last character inserted (i.e., the value to pass in as cursor the 390 * next time this method is called). Note that n is interpreted as a large 391 * positive integer (not a negative integer) if its sign bit is set. 392 */ 393 private static int intIntoCharArray(char[] buf, int cursor, int n) { 394 // Calculate digits two-at-a-time till remaining digits fit in 16 bits 395 while ((n & 0xffff0000) != 0) { 396 /* 397 * Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8. 398 * This computation is slightly different from the corresponding 399 * computation in intToString: the shifts before and after 400 * multiply can't be combined, as that would yield the wrong result 401 * if n's sign bit were set. 402 */ 403 int q = (int) ((0x51EB851FL * (n >>> 2)) >>> 35); 404 int r = n - 100*q; 405 buf[--cursor] = ONES[r]; 406 buf[--cursor] = TENS[r]; 407 n = q; 408 } 409 410 // Calculate remaining digits one-at-a-time for performance 411 while (n != 0) { 412 // Compute q = n / 10 and r = n % 10 as per "Hacker's Delight" 10-8 413 int q = (0xCCCD * n) >>> 19; 414 int r = n - 10*q; 415 buf[--cursor] = DIGITS[r]; 416 n = q; 417 } 418 return cursor; 419 } 420 421 public static String intToBinaryString(int i) { 422 int bufLen = 32; // Max number of binary digits in an int 423 char[] buf = new char[bufLen]; 424 int cursor = bufLen; 425 426 do { 427 buf[--cursor] = DIGITS[i & 1]; 428 } while ((i >>>= 1) != 0); 429 430 return new String(cursor, bufLen - cursor, buf); 431 } 432 433 public static String longToBinaryString(long v) { 434 int i = (int) v; 435 if (v >= 0 && i == v) { 436 return intToBinaryString(i); 437 } 438 439 int bufLen = 64; // Max number of binary digits in a long 440 char[] buf = new char[bufLen]; 441 int cursor = bufLen; 442 443 do { 444 buf[--cursor] = DIGITS[((int) v) & 1]; 445 } while ((v >>>= 1) != 0); 446 447 return new String(cursor, bufLen - cursor, buf); 448 } 449 450 public static String intToHexString(int i) { 451 int bufLen = 8; // Max number of hex digits in an int 452 char[] buf = new char[bufLen]; 453 int cursor = bufLen; 454 455 do { 456 buf[--cursor] = DIGITS[i & 0xf]; 457 } while ((i >>>= 4) != 0); 458 459 return new String(cursor, bufLen - cursor, buf); 460 } 461 462 public static String longToHexString(long v) { 463 int i = (int) v; 464 if (v >= 0 && i == v) { 465 return intToHexString(i); 466 } 467 468 int bufLen = 16; // Max number of hex digits in a long 469 char[] buf = new char[bufLen]; 470 int cursor = bufLen; 471 472 do { 473 buf[--cursor] = DIGITS[((int) v) & 0xF]; 474 } while ((v >>>= 4) != 0); 475 476 return new String(cursor, bufLen - cursor, buf); 477 } 478 479 public static String intToOctalString(int i) { 480 int bufLen = 11; // Max number of octal digits in an int 481 char[] buf = new char[bufLen]; 482 int cursor = bufLen; 483 484 do { 485 buf[--cursor] = DIGITS[i & 7]; 486 } while ((i >>>= 3) != 0); 487 488 return new String(cursor, bufLen - cursor, buf); 489 } 490 491 public static String longToOctalString(long v) { 492 int i = (int) v; 493 if (v >= 0 && i == v) { 494 return intToOctalString(i); 495 } 496 int bufLen = 22; // Max number of octal digits in a long 497 char[] buf = new char[bufLen]; 498 int cursor = bufLen; 499 500 do { 501 buf[--cursor] = DIGITS[((int) v) & 7]; 502 } while ((v >>>= 3) != 0); 503 504 return new String(cursor, bufLen - cursor, buf); 505 } 506 507 /** 508 * Returns a string composed of the specified characters. Note that the 509 * autoboxing does *not* result in an extra copy of the char array: we are 510 * using a package-private string constructor that incorporates the 511 * "autoboxing array" into the new string. 512 */ 513 private static String stringOf(char... args) { 514 return new String(0, args.length, args); 515 } 516 } 517