28

私はなぜ Java のバイト範囲が -128 から 127 なのかを読み ました。 それは言う

128 は 10000000 です。反転すると 01111111 になり、1 を追加すると 10000000 になります。

したがって、-128 は 10000000 であると結論付けます

したがって、+128 は 8 ビットの 2 の補数で表すことはできませんが、9 ビットで表すことができるということです。したがって、128 は 010000000 であり、その 2 の補数を取ると、-128 は 110000000 になります。

-128 10000000 または 110000000 の表現はそうですか? 表現はビット依存ですか?

-128 を 10000000 として書き込むのではなく、単純に下位範囲 -127 を 8 ビットにしないのはなぜですか?

4

5 に答える 5

48

符号なしバイトの範囲が-128〜127であるのはなぜですか?

そうではありません。符号なしバイト(8ビットを想定)は0〜255です。

2の補数を使用する符号付きバイトの範囲は、 2の補数の定義から直接、-128〜127です。

01111111 = +127
01111110 = +126
01111101 = +125
...
00000001 = +1
00000000 =  0
11111111 = -1
...
10000010 = -126
10000001 = -127
10000000 = -128

-128 10000000または110000000の表現もそうですか?

8ビットでは、それ10000000は、仮想の9ビット表現では110000000です。

単純に8ビットの下限範囲を-127にしないのはなぜですか?

範囲を人為的に-127に制限しても、あまり達成されません。完全に有効な値を許可せず、一般的にコードをより複雑にします(ビットパターンで他に何をします10000000か?)。

于 2012-07-11T13:33:45.850 に答える
18

-128 10000000 または 110000000 の表現はそうですか? 表現はビット依存ですか?

はい、2 の補数表現はビット依存です

-128 を 10000000 と書く代わりに、単純に下位範囲 -127 を 8 ビットにしない理由

2^8 = 256. したがって、どの表現スキームを使用しても、256 の異なる値を表現できるはずです。

円を描くと、2 の補数系がいかに優れているかがわかります。

最初にこの表を見てください:

Bits    Unsigned 2's complement
00000000    0   0
00000001    1   1
00000010    2   2
01111110    126     126
01111111    127     127
10000000    128     −128
10000001    129     −127
10000010    130     −126
11111110    254     −2
11111111    255     −1

2 の補数システムの場合、このシステムを理解するために円を描くことができます。

こちらが4bit版。自分で簡単に 8 ビット版を開発できます。この円は、この 2 の補数系が実際に何であるかを表しています。その循環システム。つまり、その表現は、指定した「スパン」に依存します。これが、負の数の 8 ビット バージョンが同じ負の数の 16 ビット バージョンと異なる理由です。丸で示した 4bit バージョンの同じ負の数を、表で示した 8bit バージョンと比較できます。

                      0000  0
                 1111  -1     0001  1


        1110  -2                       0010  2




  1101  -3                                   0011  3



1100  -4                                       0100  4



  1011  -5                                   0101  5




        1010  -6                       0110  6


                 1001  -7     0111  7
                          1000  -8

ちなみに、2 の補数演算は、コンピュータ内の「固定」幅の計算ストレージ (レジスタ、メモリなど) でうまく機能します。

第 1 世代のコンピューターでは、ネイティブの 10 進数演算を提供する傾向がありました。しかし、これは「補数」または「循環」スキームを支持してすぐに放棄されました。10 進演算はコンピューターの観点からは奇妙だからです。「私たちの指は10本ある」から当然だと思います。これらの指は、私たちの祖先の最初の計算ツールでした。10進法がとても自然だと思うのはそのためです。それは私たちの遺伝子に組み込まれています。

于 2012-07-11T13:56:39.880 に答える
6

2の補数の代替案は次のようになります。

  • 「負のゼロ」のために問題がある1の補数
  • 符号/大きさ、これも負のゼロを持ちます
  • に意味を割り当てない10000000でください。この場合、符号付き8ビット整数を受け入れる多くの関数は、その無効な値をチェックする必要があり、時間を浪費します。(コードがこのビットパターンを整数NaNとして扱う架空のハードウェアで実行されている場合を除きます。)

そのビットパターンに意味を割り当てる方が簡単で、2の補数表現の自然な意味は-128です。

たとえば、2の補数では、が負であるかどうかをチェックすることは、最上位ビットが設定されているかどうかをチェックすることになります。10000000が無効であるバリアントでは、それは(擬似コード)です。

if (highest_bit_zero(x))
    return false;
else if (x == 0b10000000)
    ERROR
else
    return true;

エラーの処理方法を決定します:)

于 2012-07-11T13:36:24.973 に答える
3

-128 10000000 または 110000000 の表現はそうですか? 表現はビット依存ですか?

9 ビットの世界では、110000000 になります。16 ビットの世界では、1111111110000000 になります。少なくとも、2 の補数について話している限りは。

-128 を 10000000 として書き込むのではなく、単に 8 ビットの下位範囲を -127 にしないのはなぜですか?

larsmans が指摘したように、「無効な」値になってしまうため、常にチェックする必要があります。2 の補数が選択されたのは、ALU が処理しやすいためです。バイト幅が 2 の累乗になるように選択されているのと同じように (常にそうであるとは限りません)。ハードウェア レベルでは、2 の補数の加算は符号なしと同じであるため、特別な命令や追加のハードウェアは必要ありません (1 の補数とは異なります)。

このままでは、最上位ビットが設定されている値はすべて負であり、最上位ビットが設定されていない値はすべて非負 (正またはゼロ) です。簡単ですね。負の範囲が正の範囲よりも 1 大きいのは、単純に 2 の補数を維持しようとした結果です。

于 2012-07-11T13:45:37.827 に答える