整数演算・フラグ・2の補数
序論
コンピュータにおける整数演算は、人間が行う四則演算とは異なり、
「固定されたビット幅」と「解釈規則」によって成立している。
本節では、8ビット整数を例に、加算・フラグ・2の補数が
どのような必然性を持って設計されているかを説明する。
本論
1. ビット幅と加算の現実
11111111 + 00000001 ----------- 1 00000000
上の図は、8ビット同士の加算である。
結果として9ビット目が発生している。
この最上位ビットは保存できず、carry として扱われる。
重要なのは、carry は「意味」ではなく、
単に「ビット幅を超えた」という事実を示している点である。
2. unsigned と signed の違い
11111111 (unsigned) = 255
unsigned(符号なし)として解釈した場合、
8ビットで表現できる最大値は 255 である。
そこに 1 を足すと、数学的には 256 となり、
9ビット目が必要になる。
これが carry が発生する理由である。
3. 2の補数による符号表現
8ビット: 0xxxxxxx = 正の数 1xxxxxxx = 負の数
2の補数表現では、最上位ビット(MSB)が符号を示す。
MSB が 0 なら正、1 なら負と考えてよい。
これは「覚え方」ではなく、設計結果である。
4. なぜ 2の補数が必要なのか
00000101 (+5) + 11111011 (-5) ----------- 1 00000000
-5 は +5 のビット反転に 1 を加えたもの(2の補数)である。
この演算結果は 0 となり、carry は無視される。
この仕組みにより、CPU は
引き算を実装せず、足し算だけで減算を実現できる。
5. なぜ 8ビット演算に 9ビット目が必要なのか
01111111 (+127) + 00000001 (+1) ----------- 10000000 (-128)
正の数同士を足したにもかかわらず、
結果が負になっている。
これは数値の保存自体は成功しているが、
意味が破綻している状態である。
この「意味の破綻」を検出するために、
CPU は carry とは別に overflow フラグを持つ。
6. carry と overflow の違い
carry : ビット幅を超えたか overflow : 符号の意味が壊れたか
carry は物理的事実、
overflow は論理的矛盾を示す。
両者は独立した情報である。
結論
2の補数は単なる表記法ではなく、
「加算回路だけで整数演算を完結させる」
という設計思想の結果である。
8ビット演算における 9ビット目、
carry と overflow の分離、
符号ビットの解釈は、
すべて必然的に導かれている。
Q&A
Q. なぜ MSB が 1 だと負になるのですか?
A. 2の補数では、ビット列全体を
「加算が閉じる数体系」として設計しているため、
最上位ビットが重みとして負方向に働く。
Q. なぜ引き算回路を作らないのですか?
A. 足し算回路だけで減算が可能になれば、
ハードウェアが単純になり、速く、壊れにくくなる。
Q. carry を無視してよいのはなぜですか?
A. 保存できるビット幅を超えた情報は、
その数値体系では意味を持たないためである。