• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static final char[] UPPER_CASE_DIGITS = {
112         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
113         'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
114         'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
115         'U', 'V', 'W', 'X', 'Y', 'Z'
116     };
117 
IntegralToString()118     private IntegralToString() {
119     }
120 
121     /**
122      * Equivalent to Integer.toString(i, radix).
123      */
intToString(int i, int radix)124     public static String intToString(int i, int radix) {
125         if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
126             radix = 10;
127         }
128         if (radix == 10) {
129             return intToString(i);
130         }
131 
132         /*
133          * If i is positive, negate it. This is the opposite of what one might
134          * expect. It is necessary because the range of the negative values is
135          * strictly larger than that of the positive values: there is no
136          * positive value corresponding to Integer.MIN_VALUE.
137          */
138         boolean negative = false;
139         if (i < 0) {
140             negative = true;
141         } else {
142             i = -i;
143         }
144 
145         int bufLen = radix < 8 ? 33 : 12;  // Max chars in result (conservative)
146         char[] buf = new char[bufLen];
147         int cursor = bufLen;
148 
149         do {
150             int q = i / radix;
151             buf[--cursor] = DIGITS[radix * q - i];
152             i = q;
153         } while (i != 0);
154 
155         if (negative) {
156             buf[--cursor] = '-';
157         }
158 
159         return new String(cursor, bufLen - cursor, buf);
160     }
161 
162     /**
163      * Equivalent to Integer.toString(i).
164      */
165     public static String intToString(int i) {
166         return convertInt(null, i);
167     }
168 
169     /**
170      * Equivalent to sb.append(Integer.toString(i)).
171      */
172     public static void appendInt(AbstractStringBuilder sb, int i) {
173         convertInt(sb, i);
174     }
175 
176     /**
177      * Returns the string representation of i and leaves sb alone if sb is null.
178      * Returns null and appends the string representation of i to sb if sb is non-null.
179      */
180     private static String convertInt(AbstractStringBuilder sb, int i) {
181         boolean negative = false;
182         String quickResult = null;
183         if (i < 0) {
184             negative = true;
185             i = -i;
186             if (i < 100) {
187                 if (i < 0) {
188                     // If -n is still negative, n is Integer.MIN_VALUE
189                     quickResult = "-2147483648";
190                 } else {
191                     quickResult = SMALL_NEGATIVE_VALUES[i];
192                     if (quickResult == null) {
193                         SMALL_NEGATIVE_VALUES[i] = quickResult =
194                                 i < 10 ? stringOf('-', ONES[i]) : stringOf('-', TENS[i], ONES[i]);
195                     }
196                 }
197             }
198         } else {
199             if (i < 100) {
200                 quickResult = SMALL_NONNEGATIVE_VALUES[i];
201                 if (quickResult == null) {
202                     SMALL_NONNEGATIVE_VALUES[i] = quickResult =
203                             i < 10 ? stringOf(ONES[i]) : stringOf(TENS[i], ONES[i]);
204                 }
205             }
206         }
207         if (quickResult != null) {
208             if (sb != null) {
209                 sb.append0(quickResult);
210                 return null;
211             }
212             return quickResult;
213         }
214 
215         int bufLen = 11; // Max number of chars in result
216         char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen];
217         int cursor = bufLen;
218 
219         // Calculate digits two-at-a-time till remaining digits fit in 16 bits
220         while (i >= (1 << 16)) {
221             // Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8
222             int q = (int) ((0x51EB851FL * i) >>> 37);
223             int r = i - 100*q;
224             buf[--cursor] = ONES[r];
225             buf[--cursor] = TENS[r];
226             i = q;
227         }
228 
229         // Calculate remaining digits one-at-a-time for performance
230         while (i != 0) {
231             // Compute q = n/10 and r = n % 10 as per "Hacker's Delight" 10-8
232             int q = (0xCCCD * i) >>> 19;
233             int r = i - 10*q;
234             buf[--cursor] = DIGITS[r];
235             i = q;
236         }
237 
238         if (negative) {
239             buf[--cursor] = '-';
240         }
241 
242         if (sb != null) {
243             sb.append0(buf, cursor, bufLen - cursor);
244             return null;
245         } else {
246             return new String(cursor, bufLen - cursor, buf);
247         }
248     }
249 
250     /**
251      * Equivalent to Long.toString(v, radix).
252      */
253     public static String longToString(long v, int radix) {
254         int i = (int) v;
255         if (i == v) {
256             return intToString(i, radix);
257         }
258 
259         if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
260             radix = 10;
261         }
262         if (radix == 10) {
263             return longToString(v);
264         }
265 
266         /*
267          * If v is positive, negate it. This is the opposite of what one might
268          * expect. It is necessary because the range of the negative values is
269          * strictly larger than that of the positive values: there is no
270          * positive value corresponding to Integer.MIN_VALUE.
271          */
272         boolean negative = false;
273         if (v < 0) {
274             negative = true;
275         } else {
276             v = -v;
277         }
278 
279         int bufLen = radix < 8 ? 65 : 23;  // Max chars in result (conservative)
280         char[] buf = new char[bufLen];
281         int cursor = bufLen;
282 
283         do {
284             long q = v / radix;
285             buf[--cursor] = DIGITS[(int) (radix * q - v)];
286             v = q;
287         } while (v != 0);
288 
289         if (negative) {
290             buf[--cursor] = '-';
291         }
292 
293         return new String(cursor, bufLen - cursor, buf);
294     }
295 
296     /**
297      * Equivalent to Long.toString(l).
298      */
299     public static String longToString(long l) {
300         return convertLong(null, l);
301     }
302 
303     /**
304      * Equivalent to sb.append(Long.toString(l)).
305      */
306     public static void appendLong(AbstractStringBuilder sb, long l) {
307         convertLong(sb, l);
308     }
309 
310     /**
311      * Returns the string representation of n and leaves sb alone if sb is null.
312      * Returns null and appends the string representation of n to sb if sb is non-null.
313      */
314     private static String convertLong(AbstractStringBuilder sb, long n) {
315         int i = (int) n;
316         if (i == n) {
317             return convertInt(sb, i);
318         }
319 
320         boolean negative = (n < 0);
321         if (negative) {
322             n = -n;
323             if (n < 0) {
324                 // If -n is still negative, n is Long.MIN_VALUE
325                 String quickResult = "-9223372036854775808";
326                 if (sb != null) {
327                     sb.append0(quickResult);
328                     return null;
329                 }
330                 return quickResult;
331             }
332         }
333 
334         int bufLen = 20; // Maximum number of chars in result
335         char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen];
336 
337         int low = (int) (n % 1000000000); // Extract low-order 9 digits
338         int cursor = intIntoCharArray(buf, bufLen, low);
339 
340         // Zero-pad Low order part to 9 digits
341         while (cursor != (bufLen - 9)) {
342             buf[--cursor] = '0';
343         }
344 
345         /*
346          * The remaining digits are (n - low) / 1,000,000,000.  This
347          * "exact division" is done as per the online addendum to Hank Warren's
348          * "Hacker's Delight" 10-20, http://www.hackersdelight.org/divcMore.pdf
349          */
350         n = ((n - low) >>> 9) * 0x8E47CE423A2E9C6DL;
351 
352         /*
353          * If the remaining digits fit in an int, emit them using a
354          * single call to intIntoCharArray. Otherwise, strip off the
355          * low-order digit, put it in buf, and then call intIntoCharArray
356          * on the remaining digits (which now fit in an int).
357          */
358         if ((n & (-1L << 32)) == 0) {
359             cursor = intIntoCharArray(buf, cursor, (int) n);
360         } else {
361             /*
362              * Set midDigit to n % 10
363              */
364             int lo32 = (int) n;
365             int hi32 = (int) (n >>> 32);
366 
367             // midDigit = ((unsigned) low32) % 10, per "Hacker's Delight" 10-21
368             int midDigit = MOD_10_TABLE[(0x19999999 * lo32 + (lo32 >>> 1) + (lo32 >>> 3)) >>> 28];
369 
370             // Adjust midDigit for hi32. (assert hi32 == 1 || hi32 == 2)
371             midDigit -= hi32 << 2;  // 1L << 32 == -4 MOD 10
372             if (midDigit < 0) {
373                 midDigit += 10;
374             }
375             buf[--cursor] = DIGITS[midDigit];
376 
377             // Exact division as per Warren 10-20
378             int rest = ((int) ((n - midDigit) >>> 1)) * 0xCCCCCCCD;
379             cursor = intIntoCharArray(buf, cursor, rest);
380         }
381 
382         if (negative) {
383             buf[--cursor] = '-';
384         }
385         if (sb != null) {
sb.append0(buf, cursor, bufLen - cursor)386             sb.append0(buf, cursor, bufLen - cursor);
387             return null;
388         } else {
389             return new String(cursor, bufLen - cursor, buf);
390         }
391     }
392 
393     /**
394      * Inserts the unsigned decimal integer represented by n into the specified
395      * character array starting at position cursor.  Returns the index after
396      * the last character inserted (i.e., the value to pass in as cursor the
397      * next time this method is called). Note that n is interpreted as a large
398      * positive integer (not a negative integer) if its sign bit is set.
399      */
intIntoCharArray(char[] buf, int cursor, int n)400     private static int intIntoCharArray(char[] buf, int cursor, int n) {
401         // Calculate digits two-at-a-time till remaining digits fit in 16 bits
402         while ((n & 0xffff0000) != 0) {
403             /*
404              * Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8.
405              * This computation is slightly different from the corresponding
406              * computation in intToString: the shifts before and after
407              * multiply can't be combined, as that would yield the wrong result
408              * if n's sign bit were set.
409              */
410             int q = (int) ((0x51EB851FL * (n >>> 2)) >>> 35);
411             int r = n - 100*q;
412             buf[--cursor] = ONES[r];
413             buf[--cursor] = TENS[r];
414             n = q;
415         }
416 
417         // Calculate remaining digits one-at-a-time for performance
418         while (n != 0) {
419             // Compute q = n / 10 and r = n % 10 as per "Hacker's Delight" 10-8
420             int q = (0xCCCD * n) >>> 19;
421             int r = n - 10*q;
422             buf[--cursor] = DIGITS[r];
423             n = q;
424         }
425         return cursor;
426     }
427 
intToBinaryString(int i)428     public static String intToBinaryString(int i) {
429         int bufLen = 32;  // Max number of binary digits in an int
430         char[] buf = new char[bufLen];
431         int cursor = bufLen;
432 
433         do {
434             buf[--cursor] = DIGITS[i & 1];
435         }  while ((i >>>= 1) != 0);
436 
437         return new String(cursor, bufLen - cursor, buf);
438     }
439 
longToBinaryString(long v)440     public static String longToBinaryString(long v) {
441         int i = (int) v;
442         if (v >= 0 && i == v) {
443             return intToBinaryString(i);
444         }
445 
446         int bufLen = 64;  // Max number of binary digits in a long
447         char[] buf = new char[bufLen];
448         int cursor = bufLen;
449 
450         do {
451             buf[--cursor] = DIGITS[((int) v) & 1];
452         }  while ((v >>>= 1) != 0);
453 
454         return new String(cursor, bufLen - cursor, buf);
455     }
456 
appendByteAsHex(StringBuilder sb, byte b, boolean upperCase)457     public static StringBuilder appendByteAsHex(StringBuilder sb, byte b, boolean upperCase) {
458         char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
459         sb.append(digits[(b >> 4) & 0xf]);
460         sb.append(digits[b & 0xf]);
461         return sb;
462     }
463 
byteToHexString(byte b, boolean upperCase)464     public static String byteToHexString(byte b, boolean upperCase) {
465         char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
466         char[] buf = new char[2]; // We always want two digits.
467         buf[0] = digits[(b >> 4) & 0xf];
468         buf[1] = digits[b & 0xf];
469         return new String(0, 2, buf);
470     }
471 
bytesToHexString(byte[] bytes, boolean upperCase)472     public static String bytesToHexString(byte[] bytes, boolean upperCase) {
473         char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
474         char[] buf = new char[bytes.length * 2];
475         int c = 0;
476         for (byte b : bytes) {
477             buf[c++] = digits[(b >> 4) & 0xf];
478             buf[c++] = digits[b & 0xf];
479         }
480         return new String(buf);
481     }
482 
intToHexString(int i, boolean upperCase, int minWidth)483     public static String intToHexString(int i, boolean upperCase, int minWidth) {
484         int bufLen = 8;  // Max number of hex digits in an int
485         char[] buf = new char[bufLen];
486         int cursor = bufLen;
487 
488         char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
489         do {
490             buf[--cursor] = digits[i & 0xf];
491         } while ((i >>>= 4) != 0 || (bufLen - cursor < minWidth));
492 
493         return new String(cursor, bufLen - cursor, buf);
494     }
495 
longToHexString(long v)496     public static String longToHexString(long v) {
497         int i = (int) v;
498         if (v >= 0 && i == v) {
499             return intToHexString(i, false, 0);
500         }
501 
502         int bufLen = 16;  // Max number of hex digits in a long
503         char[] buf = new char[bufLen];
504         int cursor = bufLen;
505 
506         do {
507             buf[--cursor] = DIGITS[((int) v) & 0xF];
508         } while ((v >>>= 4) != 0);
509 
510         return new String(cursor, bufLen - cursor, buf);
511     }
512 
intToOctalString(int i)513     public static String intToOctalString(int i) {
514         int bufLen = 11;  // Max number of octal digits in an int
515         char[] buf = new char[bufLen];
516         int cursor = bufLen;
517 
518         do {
519             buf[--cursor] = DIGITS[i & 7];
520         } while ((i >>>= 3) != 0);
521 
522         return new String(cursor, bufLen - cursor, buf);
523     }
524 
longToOctalString(long v)525     public static String longToOctalString(long v) {
526         int i = (int) v;
527         if (v >= 0 && i == v) {
528             return intToOctalString(i);
529         }
530         int bufLen = 22;  // Max number of octal digits in a long
531         char[] buf = new char[bufLen];
532         int cursor = bufLen;
533 
534         do {
535             buf[--cursor] = DIGITS[((int) v) & 7];
536         } while ((v >>>= 3) != 0);
537 
538         return new String(cursor, bufLen - cursor, buf);
539     }
540 
541     /**
542      * Returns a string composed of the specified characters. Note that the
543      * autoboxing does *not* result in an extra copy of the char array: we are
544      * using a package-private string constructor that incorporates the
545      * "autoboxing array" into the new string.
546      */
stringOf(char... args)547     private static String stringOf(char... args) {
548         return new String(0, args.length, args);
549     }
550 }
551