如何将Java long转换为* unsigned * base-X String(并返回)?
[编辑]我不接受任何涉及BigInteger或其他类似低效方法的答案.请在回答之前先阅读问题!
令人讨厌的是,Java不支持无符号数字类型.您可以使用下一个更大的类型将byte,short或int转换为unsigned,例如: short s = -10; int unsigned_short = s & 0xFFFF; 但是你不能长久地做到这一点,因为没有更大的类型. 那么,如何将一个签名的long转换为“unsigned”base-X,在我的情况下是base-36,然后返回? Long类具有这些方法,但将longs视为已签名,仅仅因为它们是. 我可以使用一些操作和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)更复杂. 解决方法long l = 0xffffffffffffffffL; // any long,e.g. -1 // to string BigInteger bi = new BigInteger(Long.toString(l & ~(1L << 63))); if (l < 0) bi = bi.setBit(64); final String b36 = bi.toString(36); System.out.println("original long:" + l); System.out.println("result 36: " + b36); // parse final BigInteger parsedBi = new BigInteger(b36,36); l = parsedBi.longValue(); if (parsedBi.testBit(64)) l = l | (1L << 63); System.out.println("parsed long = " + l); 基准测试(一百万次操作): // toString long l = 0x0ffffffffffffeffL; { final long start = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) toStringBi(l); System.out.println("BigInteger time = " + (System.currentTimeMillis() - start) + " ms."); } { final long start = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) Long.toString(l,36); System.out.println("Long.toString time = " + (System.currentTimeMillis() - start) + "ms."); } // Parsing final String b36 = toStringBi(l); final String long36 = Long.toString(l,36); { final long start = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) { final BigInteger parsedBi = new BigInteger(b36,36); l = parsedBi.longValue(); if (parsedBi.testBit(64)) l = l | (1L << 63); } System.out.println("BigInteger.parse time = " + (System.currentTimeMillis() - start) + " ms."); } { final long start = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) Long.parseLong(long36,36); System.out.println("Long.parseLong time = " + (System.currentTimeMillis() - start) + "ms."); } > BigInteger时间= 1027 ms.> Long.toString时间= 244ms.> BigInteger.parse time = 297 ms.> Long.parseLong time = 132ms. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |