加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

如何将Java long转换为* unsigned * base-X String(并返回)?

发布时间:2020-12-15 05:08:06 所属栏目:Java 来源:网络整理
导读:[编辑]我不接受任何涉及BigInteger或其他类似低效方法的答案.请在回答之前先阅读问题! 令人讨厌的是,Java不支持无符号数字类型.您可以使用下一个更大的类型将byte,short或int转换为unsigned,例如: short s = -10;int unsigned_short = s 0xFFFF; 但是你不
[编辑]我不接受任何涉及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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读