[编辑] 我不接受任何涉及 BigInteger 或其他类似低效方法的答案。在回答之前请实际阅读问题!
令人讨厌的是,Java 不支持无符号数字类型。您可以使用下一个更大的类型将字节、short 或 int 转换为无符号,例如:
short s = -10;
int unsigned_short = s & 0xFFFF;
但是你不能用 long 来做这个,因为没有更大的类型。
那么,如何将有符号的 long 转换为“无符号”base-X,在我的情况下为 base-36,然后返回?Long 类有这些方法,但将 long 视为有符号,仅仅是因为它们是有符号的。
我可能可以使用一些操作和 BigInteger 来做到这一点,但是 BigInteger非常慢,并且通过临时 BigInteger 创建来创建垃圾。我会做很多这样的转换(我认为)。我需要一种与 Long.toString(long i, int radix) 的默认实现一样高效的算法。
试图调整 Long.toString() 的代码,我得出:
final int RADIX = 36;
final char[] DIGITS = { '0', ... , 'Z' };
long value = 100;
if (value == 0) {
return "0";
} else {
char[] buf = new char[13];
int charPos = 12;
long i = value;
while (i != 0) {
buf[charPos--] = DIGITS[Math.abs((int) (i % RADIX))];
i /= RADIX;
}
return new String(buf, charPos + 1, (12 - charPos));
}
但它不能正确处理负值,尽管有 Math.abs()。
一旦这个工作,我需要反向转换,但我希望它会更容易。欢迎您也将其放入您的答案中。
[编辑] 实际上,我只是查看了 Long.parseLong(String s, int radix) 的代码,它看起来比 Long.toString(long i, int radix)更复杂。