Javaにunsignedはない
JavaにはC言語のようにunsignedは用意されていません。
Long・Integerのメソッドでunsignedを実現
変数に大きな値を格納する必要がある場合は、「int型」か「long型」を使用しましょう。
各データ型に用意されているメソッドを使うことで、符号なし整数とみなして計算できます。
Java SE 8以降では、intデータ型を使って、符号なし32ビットの整数を表せます。
また、同じくJava SE 8以降でlongデータ型を使って、符号なし64ビットを表すことが可能です。
具体的に使用できるメソッドは次の通りです。
- compareUnsignedメソッド:2つのint値(long値)を符号なしとして処理して数値的に比較
- divideUnsignedメソッド:第1引数を第2引数で除算した符号なしの商を返す。各引数と結果は符号なしの値として解釈される
- remainderUnsignedメソッド:第1引数を第2引数で割った符号なしの余りを返す。各引数と結果は符号なしの値として解釈される
- toUnsignedStringメソッド:引数の文字列表現を、符号なし10進値として返す
- parseUnsignedInt(parseUnsignedLong)メソッド:文字列の引数を符号なし10進数の整数として構文解析
参考:Integer (Java Platform SE 8 )
参考:Long (Java Platform SE 8 )
それぞれのメソッドを使って動作を確認してみました。
■compareUnsignedメソッドの記述例 public class Main { public static void main(String[] args) { int x = 10, y = 10; System.out.println("x=yの場合:" + Integer.compareUnsigned(x, y)); x = 10; y = 20; System.out.println("x<yの場合:" + Integer.compareUnsigned(x, y)); x = 30; y = 20; System.out.println("x>yの場合:" + Integer.compareUnsigned(x, y)); x = -30; y = 20; System.out.println("x<yの場合だが符号なしの値として比較するので「1」になる:" + Integer.compareUnsigned(x, y)); long z = 10, w = 10; System.out.println("z=wの場合:" + Long.compareUnsigned(z, w)); z = 10; w = 20; System.out.println("z<wの場合:" + Long.compareUnsigned(z, w)); z = 30; w= 20; System.out.println("z>wの場合:" + Long.compareUnsigned(z, w)); z = -30; w = 20; System.out.println("z<wの場合だが符号なしの値として比較するので「1」になる:" + Long.compareUnsigned(z, w)); } } ■実行結果 mbp:desktop potepan$ java Main x=yの場合:0 x<yの場合:-1 x>yの場合:1 x<yの場合だが符号なしの値として比較するので「1」になる:1 z=wの場合:0 z<wの場合:-1 z>wの場合:1 z<wの場合だが符号なしの値として比較するので「1」になる:1
■divideUnsignedメソッドの記述例 public class Main { public static void main(String[] args) { int x = 20, y = 10; System.out.println("int型:x = 20, y = 10"); System.out.println("符号ありのx/yの場合:" + x / y); System.out.println("符号なしのx/yの場合:" + Integer.divideUnsigned(x, y)); x = -20; y = 10; System.out.println("int型:x = -20, y = 10"); System.out.println("符号ありのx/yの場合:" + x / y); System.out.println("符号なしのx/yの場合:" + Integer.divideUnsigned(x, y)); x = 20; y = -10; System.out.println("int型:x = 20, y = -10"); System.out.println("符号ありのx/yの場合:" + x / y); System.out.println("符号なしのx/yの場合:" + Integer.divideUnsigned(x, y)); long z = 20, w = 10; System.out.println("long型:z = 20, w = 10"); System.out.println("符号ありのz/wの場合:" + z / w); System.out.println("符号なしのz/wの場合:" + Long.divideUnsigned(z, w)); z = -20; w = 10; System.out.println("long型:z = -20, w = 10"); System.out.println("符号ありのz/wの場合:" + z / w); System.out.println("符号なしのz/wの場合:" + Long.divideUnsigned(z, w)); z = 20; w = -10; System.out.println("long型:z = 20, w = -10"); System.out.println("符号ありのz/wの場合:" + z / y); System.out.println("符号なしのz/wの場合:" + Long.divideUnsigned(z, w)); } } ■実行結果 mbp:desktop potepan$ java Main int型:x = 20, y = 10 符号ありのx/yの場合:2 符号なしのx/yの場合:2 int型:x = -20, y = 10 符号ありのx/yの場合:-2 符号なしのx/yの場合:429496727 int型:x = 20, y = -10 符号ありのx/yの場合:-2 符号なしのx/yの場合:0 long型:z = 20, w = 10 符号ありのz/wの場合:2 符号なしのz/wの場合:2 long型:z = -20, w = 10 符号ありのz/wの場合:-2 符号なしのz/wの場合:1844674407370955159 long型:z = 20, w = -10 符号ありのz/wの場合:-2 符号なしのz/wの場合:0
■remainderUnsignedメソッドの記述例 public class Main { public static void main(String[] args) { int x = 20, y = 10; System.out.println("int型:x = 20, y = 10"); System.out.println("符号ありのx/yの場合:" + x / y); System.out.println("符号なしのx/yの場合:" + Integer.remainderUnsigned(x, y)); x = -20; y = 10; System.out.println("int型:x = -20, y = 10"); System.out.println("符号ありのx/yの場合:" + x / y); System.out.println("符号なしのx/yの場合:" + Integer.remainderUnsigned(x, y)); x = 20; y = -10; System.out.println("int型:x = 20, y = -10"); System.out.println("符号ありのx/yの場合:" + x / y); System.out.println("符号なしのx/yの場合:" + Integer.remainderUnsigned(x, y)); long z = 20, w = 10; System.out.println("long型:z = 20, w = 10"); System.out.println("符号ありのz/wの場合:" + z / w); System.out.println("符号なしのz/wの場合:" + Long.remainderUnsigned(z, w)); z = -20; w = 10; System.out.println("long型:z = -20, w = 10"); System.out.println("符号ありのz/wの場合:" + z / w); System.out.println("符号なしのz/wの場合:" + Long.remainderUnsigned(z, w)); z = 20; w = -10; System.out.println("long型:z = 20, w = -10"); System.out.println("符号ありのz/wの場合:" + z / y); System.out.println("符号なしのz/wの場合:" + Long.remainderUnsigned(z, w)); } } ■実行結果 mbp:desktop potepan$ java Main int型:x = 20, y = 10 符号ありのx/yの場合:2 符号なしのx/yの場合:0 int型:x = -20, y = 10 符号ありのx/yの場合:-2 符号なしのx/yの場合:6 int型:x = 20, y = -10 符号ありのx/yの場合:-2 符号なしのx/yの場合:20 long型:z = 20, w = 10 符号ありのz/wの場合:2 符号なしのz/wの場合:0 long型:z = -20, w = 10 符号ありのz/wの場合:-2 符号なしのz/wの場合:6 long型:z = 20, w = -10 符号ありのz/wの場合:-2 符号なしのz/wの場合:20
■toUnsignedStringメソッドの記述例 public class Main { public static void main(String[] args) { int i = Integer.MAX_VALUE; System.out.println("Integer.MAX_VALUE:" + i); i = Integer.MAX_VALUE + 1; System.out.println("符号ありの場合:" + i); System.out.println("符号なしの場合:" + Integer.toUnsignedString(i)); long l = Long.MAX_VALUE; System.out.println("Long.MAX_VALUE:" + l); l = Long.MAX_VALUE + 1; System.out.println("符号ありの場合:" + l); System.out.println("符号なしの場合:" + Long.toUnsignedString(l)); } } ■実行結果 mbp:desktop potepan$ java Main Integer.MAX_VALUE:2147483647 符号ありの場合:-2147483648 符号なしの場合:2147483648 Long.MAX_VALUE:9223372036854775807 符号ありの場合:-9223372036854775808 符号なしの場合:9223372036854775808
■parseUnsignedInt(parseUnsignedLong)メソッドの記述例 public class Main { public static void main(String[] args) { int i01 = Integer.parseUnsignedInt("2147483647"); System.out.println(i01); int i02 = Integer.parseUnsignedInt("2147483648"); System.out.println(i02); long l01 = Long.parseUnsignedLong("9223372036854775807"); System.out.println(l01); long l02 = Long.parseUnsignedLong("9223372036854775808"); System.out.println(l02); } } ■実行結果 mbp:desktop potepan$ java Main 2147483647 -2147483648 9223372036854775807 -9223372036854775808
どのメソッドも、符号なしで計算できているのがわかりますね。
このように、int型・long型のメソッドを活用することで、unsignedを擬似的に実現できます。
Java 9からUnsignedクラスが導入
Java 9から新しくUnsignedクラスが導入されており、値が符号なしデータ型であることを示します。
詳しくは、Javaのリファレンスを参考にしてみてくださいね。