減算するとします:0000 0000-(-1)
つまり:(2の補数)
0000 0000
- 1111 1111
---------
= ???? ????
何が起こるのか、私の脳は今本当に私と一緒に遊んでいます、それは前に完全にうまくいきました、私はそれが私を台無しにしているオーバーフローだと思います、誰かがこれにいくらかのクリアランスを与えることができますか:)?
減算するとします:0000 0000-(-1)
つまり:(2の補数)
0000 0000
- 1111 1111
---------
= ???? ????
何が起こるのか、私の脳は今本当に私と一緒に遊んでいます、それは前に完全にうまくいきました、私はそれが私を台無しにしているオーバーフローだと思います、誰かがこれにいくらかのクリアランスを与えることができますか:)?
減数の 2 の補数をとり、被減数に追加します。
0000 0000
- 1111 1111
...
0000 0000
+ 0000 0001
-----------
0000 0001
2 の補数である 1 (バイナリ 0000 0001) を加算することで、-1 (バイナリ 1111 1111) を引くことができます。したがって、10 進数では、0-(-1)=0+1=1 :-)
(-11..11) になります。10 進数と同様に、単純な減算の代わりにビット演算を使用しない限り、符号は符号のままで (0-x) は (-x) のままです。
私の直感では、0 - (-1)
は に等しい0+1
か、単にである必要があります1
。
なぜだろうと思ったら、ビットごとに減算を実行してみてください。
0 - 1 = 10 - 1 = 1, setting borrow to 1.
0 - 1 - borrow = 10 - 1 - 1 = 0, borrow = 1
etc..
また、手動でバイナリ減算を行うことは避けてください。2 の補数の考え方は、代わりに逆数を加算することで減算を実行する簡単な方法を提供することです。
ハードウェアが行う方法は、2 番目のオペランドを反転し、最下位ビット レーンのキャリーを 1 に加算して加算を実行することです。オペランドは記され、キャリーインセット。
隣の数字から借りる鉛筆と紙のスタイルで行うことができますが、10進数と比べると少し間抜けに感じます. 10 進数で 1000 マイナス 1 と言うと、右側のゼロは 10 になります。これは 10 を底とするためです。次に、その隣の 0 も借りて 10 にしますが、右側に 1 つ借りて 9 にします。一番上の行が 9 9 10 になるまで続き、0 0 1 を引いて 999 を取得します。基数 2 の 0b1000 (10 進数の 8) から 0b0001 を引くと、同じことが起こり、右のゼロが左から借りて 2 または 0b10 になります。これは基数 2 で、その隣のゼロは借用する必要があり、0b10 になり、右に 1 を貸して 1 にするなど、一番上の行は 1 1 0b10 で、一番下の行は 0 0 1 です。列と 0b111 または 7 10 進数を取得します。
したがって、すべてのゼロからすべての 1 を引いたものは、最初の借用の後、一番上の行は 1 1 1 1 1 1 1 0b10 であり、一番下の行は 0 0 0 0 0 0 0 0 のままで、列を減算すると 0 0 0 0 0 0 が得られます。 0 1.