3

我的组件被传递了一个长值,我稍后将其用作缓存中的键。密钥本身是 long 值的字符串表示形式,就好像它是无符号的 64 位值一样。也就是说,当我的组件被交给-2944827264075010823L时,我需要将其转换为字符串键“15501916809634540793”。

我有一个解决方案,但它似乎是蛮力的,它让我有点反胃。本质上,我将 long 转换为十六进制字符串表示形式(因此 -2944827264075010823L 变为“d721df34a7ec6cf9”)并将十六进制字符串转换为 BigInteger:

String longValueAsHexString = convertLongToHexString(longValue);
BigInteger bi = new BigInteger(longValueAsHexString, 16);
String longValueString = bi.toString();

然后我使用 longValueString 作为进入缓存的键。

我不能使用 Long.toString(longValue,16),因为它返回绝对值的十六进制字符串,前缀为“-”。

所以我的 convertLongToHexString 看起来像这样:

long mask = 0x00000000ffffffffL;
long bottomHalf = number & mask;
long upperHalf = (number >> 32) & mask;
String bottomHalfString = Long.toString(bottomHalf, 16);
if (bottomHalfString.length() != 8) {
    String zeroes = "0000000000000000";
    bottomHalfString = zeroes.substring(16-bottomHalfString.length()) + bottomHalfString;
}
return Long.toString(upperHalf,16)+bottomHalfString;

必须有一种更优雅的方式来做到这一点。有什么建议么?

4

4 回答 4

5

这是我的实现。我已经对其进行了重构,使其具有一个接受 along并返回一个字符串的函数。:-)

import java.math.BigInteger;

class UInt64Test {
    public static void main(String[] args) {
        for (String arg : args)
            System.out.println(toUnsignedString(Long.parseLong(arg)));
    }

    private static final BigInteger B64 = BigInteger.ZERO.setBit(64);
    public static String toUnsignedString(long num) {
        if (num >= 0)
            return String.valueOf(num);
        return BigInteger.valueOf(num).add(B64).toString();
    }
}
于 2008-10-20T05:21:54.087 回答
4

我认为克里斯的答案更好,但这是另一个只是为了好玩。

public static String longUnsignedString(long l) {
  byte[] bytes = new byte[9];

  for (int i = 1; i < 9; i++) {
     bytes[i] = (byte) ((l >> ((8 - i) * 8)) & 255);
  }

  return (new BigInteger(bytes)).toString();
}
于 2008-10-20T06:04:32.330 回答
2

晚了五年,但这是一个不使用BigInteger字节数组的实现。
相反,它模拟无符号除法一步并将其余部分卸载到标准库函数:

public static String unsignedToString(long n) {
    long temp = (n >>> 1) / 5;  // Unsigned divide by 10 and floor
    if (temp == 0)
        return Integer.toString((int)n);  // Single digit
    else
        return Long.toString(temp) + (n - temp * 10);  // Multiple digits
}
于 2013-05-29T16:14:05.053 回答
1

无位实现:

    byte[] bytes = ByteBuffer.allocate(8).putLong(1023L).array();
    System.out.println(new BigInteger(bytes).toString(2));

问候,亚历克斯

于 2011-09-14T13:41:01.193 回答