package java.lang;
/**
* Converts integral types to strings. This class is public but hidden so that it can also be
* used by java.util.Formatter to speed up %d. This class is in java.lang so that it can take
* advantage of the package-private String constructor.
*
* The most important methods are appendInt/appendLong and intToString(int)/longToString(int).
* The former are used in the implementation of StringBuilder, StringBuffer, and Formatter, while
* the latter are used by Integer.toString and Long.toString.
*
* The append methods take AbstractStringBuilder rather than Appendable because the latter requires
* CharSequences, while we only have raw char[]s. Since much of the savings come from not creating
* any garbage, we can't afford temporary CharSequence instances.
*
* One day the performance advantage of the binary/hex/octal specializations will be small enough
* that we can lose the duplication, but until then this class offers the full set.
*
* @hide
*/
public final class IntegralToString {
/**
* When appending to an AbstractStringBuilder, this thread-local char[] lets us avoid
* allocation of a temporary array. (We can't write straight into the AbstractStringBuilder
* because it's almost as expensive to work out the exact length of the result as it is to
* do the formatting. We could try being conservative and "delete"-ing the unused space
* afterwards, but then we'd need to duplicate convertInt and convertLong rather than share
* the code.)
*/
private static final ThreadLocal<char[]> BUFFER = new ThreadLocal<char[]>() {
@Override protected char[] initialValue() {
return new char[20]; // Maximum length of a base-10 long.
}
};
/**
* These tables are used to special-case toString computation for
* small values. This serves three purposes: it reduces memory usage;
* it increases performance for small values; and it decreases the
* number of comparisons required to do the length computation.
* Elements of this table are lazily initialized on first use.
* No locking is necessary, i.e., we use the non-volatile, racy
* single-check idiom.
*/
private static final String[] SMALL_NONNEGATIVE_VALUES = new String[100];
private static final String[] SMALL_NEGATIVE_VALUES = new String[100];
/** TENS[i] contains the tens digit of the number i, 0 <= i <= 99. */
private static final char[] TENS = {
'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',
'4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
'5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
'6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
'7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
'8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
'9', '9', '9', '9', '9', '9', '9', '9', '9', '9'
};
/** Ones [i] contains the tens digit of the number i, 0 <= i <= 99. */
private static final char[] ONES = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
};
/**
* Table for MOD / DIV 10 computation described in Section 10-21
* of Hank Warren's "Hacker's Delight" online addendum.
* http://www.hackersdelight.org/divcMore.pdf
*/
private static final char[] MOD_10_TABLE = {
0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 0
};
/**
* The digits for every supported radix.
*/
private static final char[] DIGITS = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'
};
private IntegralToString() {
}
/**
* Equivalent to Integer.toString(i, radix).
*/
public static String intToString(int i, int radix) {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
radix = 10;
}
if (radix == 10) {
return intToString(i);
}
/*
* If i 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 Integer.MIN_VALUE.
*/
boolean negative = false;
if (i < 0) {
negative = true;
} else {
i = -i;
}
int bufLen = radix < 8 ? 33 : 12; // Max chars in result (conservative)
char[] buf = new char[bufLen];
int cursor = bufLen;
do {
int q = i / radix;
buf[--cursor] = DIGITS[radix * q - i];
i = q;
} while (i != 0);
if (negative) {
buf[--cursor] = '-';
}
return new String(cursor, bufLen - cursor, buf);
}
/**
* Equivalent to Integer.toString(i).
*/
public static String intToString(int i) {
return convertInt(null, i);
}
/**
* Equivalent to sb.append(Integer.toString(i)).
*/
public static void appendInt(AbstractStringBuilder sb, int i) {
convertInt(sb, i);
}
/**
* Returns the string representation of i and leaves sb alone if sb is null.
* Returns null and appends the string representation of i to sb if sb is non-null.
*/
private static String convertInt(AbstractStringBuilder sb, int i) {
boolean negative = false;
String quickResult = null;
if (i < 0) {
negative = true;
i = -i;
if (i < 100) {
if (i < 0) {
// If -n is still negative, n is Integer.MIN_VALUE
quickResult = "-2147483648";
} else {
String result = SMALL_NEGATIVE_VALUES[i];
if (result == null) {
SMALL_NEGATIVE_VALUES[i] = result =
i < 10 ? stringOf('-', ONES[i]) : stringOf('-', TENS[i], ONES[i]);
}
}
}
} else {
if (i < 100) {
quickResult = SMALL_NONNEGATIVE_VALUES[i];
if (quickResult == null) {
SMALL_NONNEGATIVE_VALUES[i] = quickResult =
i < 10 ? stringOf(ONES[i]) : stringOf(TENS[i], ONES[i]);
}
}
}
if (quickResult != null) {
if (sb != null) {
sb.append0(quickResult);
return null;
}
return quickResult;
}
int bufLen = 11; // Max number of chars in result
char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen];
int cursor = bufLen;
// Calculate digits two-at-a-time till remaining digits fit in 16 bits
while (i >= (1 << 16)) {
// Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8
int q = (int) ((0x51EB851FL * i) >>> 37);
int r = i - 100*q;
buf[--cursor] = ONES[r];
buf[--cursor] = TENS[r];
i = q;
}
// Calculate remaining digits one-at-a-time for performance
IntegralToString.rar_V2
版权申诉
6 浏览量
2022-09-14
21:52:43
上传
评论
收藏 4KB RAR 举报
Kinonoyomeo
- 粉丝: 77
- 资源: 1万+
最新资源
- 前端学习笔记,做一个简单的网站-学生成绩.HTML
- 基于时空图卷积(ST-GCN)的骨骼动作识别(python源码+毕业设计).zip
- 毕业设计 基于Python时空图卷积(ST-GCN)的骨骼动作识别源码+模型+示例效果图+全部数据资料(优秀项目).zip
- IPCG_SV_H9_CN_STD_V5.8.10_build240619.zip
- 一个简单的学生管理系统的示例,包括基本的学生信息管理功能
- GPT-Chorme-install
- Xshell 常用命令和优点
- 语音识别与播报系统main函数c语言代码
- curriculum_design.zip
- pyside6的特殊按钮(互锁、自锁、独占模式)文章的ui资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈