Oracleの「Primitive data types」 page では、Java 8がunsigned intおよびlongのサポートを追加することに言及しています。
int
:デフォルトでは、int
データ型は32ビットの符号付き2の補数整数であり、最小値は-2です31 および最大値231-1。 Java SE 8以降では、int
データ型を使用して、最小値が0で最大値が符号なし32ビット整数を表すことができます。 232−1。Integer
クラスを使用して、int
データ型を符号なし整数として使用します。詳細については、「数字クラス」セクションを参照してください。compareUnsigned
、divideUnsigned
などの静的メソッドは、Integer
クラスに追加され、符号なし整数の算術演算をサポートします。
long
:long
データ型は、64ビットの2の補数整数です。符号付きlong
の最小値は-2です63 および最大値263-1。 Java SE 8以降では、long
データ型を使用して、符号なし64ビットlong
を表すことができます。これは、最小値0、最大値264−1。intで提供される値よりも広い範囲の値が必要な場合に、このデータ型を使用します。Long
クラスには、compareUnsigned
、divideUnsigned
などのメソッドも含まれており、符号なしのlong
の算術演算をサポートします。
ただし、符号なしのlongまたは整数を宣言する方法はありません。たとえば、次のコードは、範囲内にある必要があるときに(リテラルは範囲外です(もちろんJava 8を使用しています)というコンパイラエラーメッセージを返します(割り当てられた値は正確に264−1):
public class Foo {
static long values = 18446744073709551615L;
public static void main(String[] args){
System.out.println(values);
}
}
それで、unsigned intまたはlongを宣言する方法はありますか?
あなたが投稿したドキュメント、および このブログ投稿 -署名されていないint/longと署名されたものの間でプリミティブを宣言するときに違いはありません。 「新しいサポート」とは、IntegerクラスとLongクラスに静的メソッドを追加することです。 Integer.divideUnsigned 。これらのメソッドを使用していない場合、2 ^ 63-1を超える「符号なし」は、負の値を持つ単純な古いlongです。
簡単なスキムから、+ /-2 ^ 31-1またはlongの場合は+/- 2 ^ 63-1の範囲外の整数定数を宣言する方法がないように見えます。範囲外の正の値に対応する負の値を手動で計算する必要があります。
Java 8でも、long
とint
はまだ署名されていますが、一部のメソッドだけが署名されていないかのように扱うです。そのような符号なしのlong
リテラルを書きたい場合は、次のようにします。
static long values = Long.parseUnsignedLong("18446744073709551615");
public static void main(String[] args) {
System.out.println(values); // -1
System.out.println(Long.toUnsignedString(values)); // 18446744073709551615
}
// Java 8
int vInt = Integer.parseUnsignedInt("4294967295");
System.out.println(vInt); // -1
String sInt = Integer.toUnsignedString(vInt);
System.out.println(sInt); // 4294967295
long vLong = Long.parseUnsignedLong("18446744073709551615");
System.out.println(vLong); // -1
String sLong = Long.toUnsignedString(vLong);
System.out.println(sLong); // 18446744073709551615
// Guava 18.0
int vIntGu = UnsignedInts.parseUnsignedInt(UnsignedInteger.MAX_VALUE.toString());
System.out.println(vIntGu); // -1
String sIntGu = UnsignedInts.toString(vIntGu);
System.out.println(sIntGu); // 4294967295
long vLongGu = UnsignedLongs.parseUnsignedLong("18446744073709551615");
System.out.println(vLongGu); // -1
String sLongGu = UnsignedLongs.toString(vLongGu);
System.out.println(sLongGu); // 18446744073709551615
/**
Integer - Max range
Signed: From −2,147,483,648 to 2,147,483,647, from −(2^31) to 2^31 – 1
Unsigned: From 0 to 4,294,967,295 which equals 2^32 − 1
Long - Max range
Signed: From −9,223,372,036,854,775,808 to 9,223,372,036,854,775,807, from −(2^63) to 2^63 − 1
Unsigned: From 0 to 18,446,744,073,709,551,615 which equals 2^64 – 1
*/
を宣言する方法はありません nsigned long or int in Java 8またはJava 9.しかし、一部のメソッドは、それらを署名なしのように扱います。例えば:
static long values = Long.parseUnsignedLong("123456789012345678");
しかし、これは変数の 宣言 ではありません。
サードパーティのライブラリを使用するオプションがある場合、 jOO ( jOOQ からのスピンオフライブラリ)があります。これは、Javaの符号なし整数のラッパータイプを提供します。これは、プリミティブ型(つまりバイトコード)が符号なしの型をサポートすることとまったく同じではありませんが、ユースケースとしてはまだ十分でしょう。
import static org.joou.Unsigned.*;
// and then...
UByte b = ubyte(1);
UShort s = ushort(1);
UInteger i = uint(1);
ULong l = ulong(1);
これらの型はすべてJava.lang.Number
を拡張し、高次のプリミティブ型とBigInteger
に変換できます。
(免責事項:私はこれらの図書館の背後にある会社で働いています)