[编辑] 在回答问题之前,请确实“阅读”问题,我不接受任何涉及BigInteger或其他类似低效方法的答案!
Java非常让人恼火的是,它不支持无符号数类型。您可以通过使用下一个更大的类型将byte、short或int转换为无符号类型,例如:
short s = -10;
int unsigned_short = s & 0xFFFF;
但是你不能使用long类型进行此操作,因为没有更大的类型。
那么,如何将有符号的long转换为“无符号”的基数X(在我的情况下为基数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)更加复杂。