1. ホーム
  2. java

[解決済み] Javaで整数をビット単位で表現するには?

2023-05-04 01:19:47

質問

Javaが内部で整数をどのように保存しているかを理解しようとしています。私はすべてのJavaのプリミティブ整数が符号付きであることを知っています(shortは除く)。それは、数値のために1バイトで利用可能な1つのより少ないビットを意味します。

私の質問は、すべての整数(正と負)は2の補数として格納されていますか、それとも負の数だけが2の補数ですか?

仕様書では x bit two's complement number . でも、よく混乱するんですよね。

例えば

  int x = 15; // Stored as binary as is?  00000000 00000000 00000000 00001111?
  int y = -22; // Stored as two complemented value? 11111111 11111111 11111111 11101010

編集

はっきり言って x = 15

   In binary as is: `00000000 00000000 00000000 00001111'
  Two's complement: `11111111 11111111 11111111 11110001`

ですから、もしあなたの答えが all であれば、数字は2の補数として格納されます。

  int x = 15; // 11111111 11111111 11111111 11110001
  int y = -22 // 11111111 11111111 11111111 11101010

ここで再び混乱は、符号は、両方が負の数であると言う。もしかしたら、私が読み間違えているのか、誤解しているのか?

編集 私の質問が紛らわしいかどうかわからない。質問を分離することを余儀なくされます。

私の質問は正確に言えば 正の数は binary as is に格納され、負の数は two's complement ?

すべて2の補数で格納されると言ったものと、負の数のみ2の補数で格納されると言った回答があります。

どのように解決するのですか?

まず、Javaのプリミティブなデータ型をまとめることから始めましょう。

バイト : バイトデータ型は8ビットの符号付き 2の補数整数 .

短い : Shortデータ型は16ビット符号付き 2の補数整数 .

int: intデータ型は32ビット符号付き 2の補数整数です。 .

long: Longデータ型は64ビット符号付き 2の補数整数です。 .

フロートです。 フロートデータ型は、単精度の 32ビットIEEE754浮動小数点 .

ダブル double データ型は、倍精度の 64ビットIEEE754浮動小数点 .

booleanです。 booleanデータ型は 1ビットの情報 .

char: charデータ型は 単一の16ビットUnicode文字 .

ソース

2の補数

"良い例は、以下のものです。 wiki にあるように、256 = 255 + 1、(255 - x) が x の補数であることに注目すると、2の補数との関係が実現されます。

0000 0111=7 2の補数は1111 1001= -7である。

のように、MSB(最上位ビット)に負の値が入るので、上記の場合は

-7 = 1001= -8 + 0+ 0+ 1

正の整数は一般に単純な2進数として保存されます(1が1、10が2、11が3、といった具合に)。

負の整数は、その絶対値の 2 の補数として格納されます。正の数の2の補数は、この表記法を使う場合、負の数となります。

ソース

この回答で何点かいただいたので、さらに情報を追加することにしました。

より詳細な回答です。

2進数で正負の数を表現する方法には、主に次の4つがあります。

  1. 符号付きマグニチュード
  2. 1の補数
  3. 二人の補数
  4. バイアス

1. 符号付きマグニチュード

最上位ビットを用いて符号を表し、残りのビットを用いて絶対値を表します。ここで 0 を表します。 正の数 であり 1 負の数 を表します。

1011 = -3
0011 = +3

この表現の方がシンプルです。しかし、10進数の足し算と同じように2進数の足し算ができないので、ハードウェアレベルでの実装が難しくなります。さらに、この方法では、2つの2進数パターンを使って0, -0 (1000) +0 (0000) .

2. 自分の補完

この表現では、与えられた数のすべてのビットを反転して、その補数を求めます。たとえば

010 = 2, so -2 = 101 (inverting all bits).

この表現の問題点は、0を表現するためにまだ2つのビットパターンが存在することです。 負の0 (1111) 正の0 (0000)

3. 2の補数

数の負を求めるには、この表現では、すべてのビットを反転させてから1ビットを足します。ビットを1つ加えることで、0を表すビットのパターンが2つある問題が解決されます。 0 (0000) .

例えば、4ビットを使って4(10進数)の2進数負表現を求めたいとします。まず、4を2進数に変換します。

4 = 0100

で、すべてのビットを反転させます。

0100 -> 1011

最後に、1ビットを追加します。

1011 + 1 = 1100.

つまり1100は、4ビットの2の補数2進数表現を使う場合、10進数で-4と等価です。

補数を求めるより速い方法は、値1として最初のビットを固定し、残りのビットを反転させることです。上記の例では、次のようになります。

0100 -> 1100
^^ 
||-(fixing this value)
|--(inverting this one)

2の補数表現は、0を表す表現が1つしかないことに加え、10進数と同じように、符号の異なる数でも2進数の値を加算します。ただし、オーバーフローの場合をチェックする必要があります。

4. バイアス

この表現は浮動小数点数のIEEE754規範で指数を表現するために使用されます。すべてのビットを0にした2進値が最小の値を表すという利点があります。また、すべてのビットが1である2進数は最大の値を表します。名前が示すように、値はバイアス(通常は 2^(n-1) または 2^(n-1)-1) を持つ n ビットの 2 進法で(正または負)符号化されます。

つまり、8 ビットを使用する場合、10 進法の値 1 は 2^(n-1) のバイアスを使用して 2 進法で、値によって表現されます。

+1 + bias = +1 + 2^(8-1) = 1 + 128 = 129
converting to binary
1000 0001