如何创建表示 Java long 的字符串,就好像它是无符号 64 位值一样

发布于 2024-07-08 06:19:34 字数 1083 浏览 6 评论 0原文

我的组件收到一个长值,稍后我将其用作缓存的键。 键本身是长值的字符串表示形式,就好像它是无符号 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;

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

My component is handed a long value that I later use as a key into a cache. The key itself is a string representation of the long value as if it were unsigned 64-bit value. That is, when my component is handed -2944827264075010823L, I need to convert that into the string key "15501916809634540793".

I have a solution, but it seems brute force and it makes me a bit queasy. Essentially, I convert the long into a hexadecimal string representation (so -2944827264075010823L becomes "d721df34a7ec6cf9") and convert the hexadecimal string into a BigInteger:

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

I then use longValueString as the key into the cache.

I cannot use Long.toString(longValue,16), because it returns the hex string for the absolute value, prefixed by a "-".

So my convertLongToHexString looks like this:

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;

There must be a more elegant way of doing this. Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦冥 2024-07-15 06:19:34

这是我的实现。 我对其进行了重构,使其具有一个采用 long 并返回字符串的函数。 :-)

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();
    }
}

Here's my implementation. I've refactored it to have a function taking a long and returning a string. :-)

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();
    }
}
野生奥特曼 2024-07-15 06:19:34

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

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();
}

I think Chris's answer is better, but here's another just for fun.

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();
}
鸠书 2024-07-15 06:19:34

晚了五年,但这里是一个不使用 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
}

Five years late, but here is an implementation that doesn't use BigInteger or byte arrays.
Instead, it emulates unsigned division for one step and offloads the rest to the standard library function:

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
}
司马昭之心 2024-07-15 06:19:34

无位实现:

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

问候,Alex

Bitless implementations:

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

regards, Alex

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文