私が見たほとんどの説明と同様に、上記の説明は 2 の補数を扱う方法については明確ですが、それらが数学的に何であるかを実際に説明していません。少なくとも整数についてはそうしようと思います。最初に、おそらくよく知られているいくつかの背景について説明します。
10 進数の仕組みを思い出してください:
2345は 2 × 10 3 + 3 × 10 2 + 4 × 10 1 + 5 × 10 0
の書き方です。
同様に、2 進数は、同じ一般的な考え方に従って0と1だけを使用して数値を記述する方法ですが、上記の 10 を 2 に置き換えます。次に、バイナリでは、
1111は1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0
の書き方であり、計算すると 15 (基数 10) になります。 8+4+2+1=15だからです。
これはすべてうまくいき、正の数には適しています。人間が10進数で行うように、負の数の前にマイナス記号を付けるだけでも構わない場合は、負の数でも機能します。それはコンピュータでも可能ですが、私は 1970 年代初頭以来、そのようなコンピュータを見たことがありません。別の議論のために理由を残しておきます。
コンピューターの場合、負の数の補数表現を使用する方が効率的であることが判明しました。そして、ここで見落とされがちなことがあります。補数表記には、通常の正の数の前にある暗黙のゼロであっても、数の数字のある種の反転が含まれます。疑問が生じるので、それは厄介です:それらすべてですか?それは考慮すべき無限の桁数になる可能性があります。
幸いなことに、コンピューターは無限を表していません。数値は特定の長さ (または必要に応じて幅) に制限されます。それでは、正の 2 進数に戻りましょう。ただし、特定のサイズがあります。これらの例では、8 桁 (「ビット」) を使用します。したがって、2 進数は実際には
00001111
または
0 × 2 7 + 0 × 2 6 + 0 × 2 5 + 0 × 2 4 + 1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0になります。
2 の補数の負を形成するには、まずすべての (2 進) 数字を補数して 11110000 を形成
し
、1 を加えて
11110001
を形成しますが、これが -15 を意味することをどのように理解すればよいでしょうか?
答えは、上位ビット (一番左のビット) の意味を変更することです。このビットは、すべての負の数に対して1になります。変更は、それが現れる数値の値への寄与の符号を変更することです。したがって、11110001
は、 - 1 × 2 7 + 1 × 2 6 + 1 × 2 5 + 1 × 2 4 +を表すと理解されます。 0 × 2 3 + 0 × 2 2 + 0 × 2 1 + 1 × 2 0
その式の前に「-」があることに注意してください。これは、符号ビットが重み -2 7、つまり -128 (基数 10) を持つことを意味します。他のすべての位置は、符号なし 2 進数の場合と同じ重みを保持します。
-15 を計算すると、
-128 + 64 + 32 + 16 + 1
になります。電卓で試してみてください。-15です。
コンピューターで負の数を表現する 3 つの主な方法のうち、2 の補数は、一般的な使用の利便性から圧倒されます。しかし、それは奇妙さを持っています。バイナリなので、可能なビットの組み合わせは偶数でなければなりません。それぞれの正の数はその負の数と組み合わせることができますが、ゼロは 1 つしかありません。ゼロを否定するとゼロになります。したがって、もう 1 つの組み合わせがあります。符号ビットが1で、それ以外はすべて0の数値です。対応する正の数は、使用されているビット数に収まりません。
この数のさらに奇妙な点は、1 を補ったり足したりして正の数を作ろうとすると、同じ負の数が返されることです。ゼロがこれを行うのは当然のようですが、これは予期せぬことであり、私たちが慣れ親しんでいる動作とはまったく異なります。コンピューターは別として、私たちは通常、この固定長の算術演算ではなく、無制限の桁数の供給を考えているからです。
これは奇妙なことの氷山の一角のようなものです。水面下にはさらに多くの待ち伏せがありますが、この議論にはそれで十分です。固定小数点演算の「オーバーフロー」を調べれば、おそらくもっと見つかるでしょう。本当にやりたいのなら、「モジュラー算術」についても調べてみてください。