How to create a string representing Java as if it were an unsigned 64-bit value

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

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

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

Then I use longValueString as the key in the cache.

I cannot use Long.toString (longValue, 16) because it returns the sixth line for an absolute value with the prefix "-".

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 should be a more elegant way to do this. Any suggestions?

+3
source share
4 answers

Here is my implementation. I edited it so that the function executes longand returns 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();
    }
}
+5
source

I think Chris answers better, but here is another one 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();
}
+4
source

, , 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
}
+2

:

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

+1

Source: https://habr.com/ru/post/1698462/


All Articles