web-dev-qa-db-ja.com

符号付き整数を符号なしlongに変換する最良の方法は?

Javaの特定のハッシュ関数については、値を符号なし整数として見るとよいでしょう(他の実装との比較など)が、Javaは符号付きの型のみをサポートします。署名済みintを「署名なし」longに変換できます。

public static final int BITS_PER_BYTE = 8;
public static long getUnsignedInt(int x) {
  ByteBuffer buf = ByteBuffer.allocate(Long.SIZE / BITS_PER_BYTE);
  buf.putInt(Integer.SIZE / BITS_PER_BYTE, x);
  return buf.getLong(0);
}
getUnsignedInt(-1); // => 4294967295

しかし、この解決策は、私たちが実際に行っていることに対してはやり過ぎのようです。同じことを達成するためのより効率的な方法はありますか?

48
maerics

このようなもの?

int x = -1;
long y = x & 0x00000000ffffffffL;

それとも何かが足りませんか?

public static long getUnsignedInt(int x) {
    return x & 0x00000000ffffffffL;
}
86
Mysticial

Java 8の標準的な方法は Integer.toUnsignedLong(someInt) です。これは @ Mysticial's answer と同等です。

33
superEb

Guava は、 UnsignedInts.toLong(int) ...に加えて、符号なし整数に関するさまざまなユーティリティを提供します。

17
Louis Wasserman

次のような関数を使用できます

public static long getUnsignedInt(int x) {
    return x & (-1L >>> 32);
}

ただし、ほとんどの場合、これを行う必要はありません。代わりに回避策を使用できます。例えば.

public static boolean unsignedEquals(int a, int b) {
    return a == b;
}

符号なしの値を使用するための回避策の例については。 署名されていないユーティリティクラス

7
Peter Lawrey

他のソリューション。

public static long getUnsignedInt(int x) {
    if(x > 0) return x;
    long res = (long)(Math.pow(2, 32)) + x;
    return res;
}
2
lmatt