コンピュータ(CPU)でなぜ負の整数の表現として2の補数を使うか

2の補数というのは何かという説明はWikipediaに譲るとします。

結論から言うと、CPU(ハードウェア)的には単なる符号なし整数の加算・減算を行っているだけなのに、人間側の解釈の仕方だけで正負の数の加算・減算を扱えるようにするためです。

いまCPUレジスタ1バイト長であるとします。で、16進数で符号なし整数0xFF(十進数で255)に1を足します。そうすると桁あふれが起こって結果としてこのレジスタの値は0(ゼロ)になります。

0xFF(255) + 1 = 0x100(256) = 0x00  [レジスタは1バイト長固定]

ここでです、もし、人間側が勝手に”1バイト長でのレジスタの値0xFFを-1という意味としよう”と決めたとします。なぜそんなことをするかといえば、そう解釈すると、

0xFF(-1) + 1 = 0

となり、都合が良いからです。

この調子で、0xFEを-2と勝手に解釈すれば…

0xFE(-2) + 2 =  0

おお~、よいですね。

では、符号なし整数で0xFE(254) + 1 = 0xFF(255)ですが、我々の符号付の解釈では…

0xFF(-2) + 1 = 0xFF(-1)

うまくいく!

とまぁ、こんな風に、符号付の計算だけのためのハードウェアをわざわざ用意しなくても、人間側の解釈だけで正負の数が表せるのが2の補数表現のうまみです。

お気楽プログラミング再開しました

4年くらい前に書いていたkissという名前のなんちゃってISLisp言語処理系をクラウドストレージから掘り出して、またいじりはじめました。

インタープリタとしてC言語で実装してありますね。setjmpなんかでLispのコントロール構造を実装してあります。

で、C言語なんですが、読めば一応わかりますが、重箱の隅は忘れているので、誉れ高いC言語のバイブルK&Rをネットで無料で調達して、リファレンスマニュアルをざっと確認しました。

いやー、いいですねプログラミングは…。

msys2をインストールして、gcc *.c でコンパイルしようとしたら、ワーニンングがたくさんでました。wchar_t関係ですね。で、頭にきたので全部charに変更して動くようにしました。昔ながらのstrcmpなんかが変な名前の関数使わなきゃいけないんでヤだったんですよね。

ただ楽しみのためだけにプログラミングすることにしました。

で、すでに偉そうにオブジェクトシステムとかジェネリックファンクションなんかも実装してあるので(そこで力尽きたみたいです)、ベクタとか残りを実装して、ノリでISOから規格書(約2万円!)もそのうち買って、規格準拠の処理系ですなんてすました顔して公開してみたいなと思っています。

 

yaccによるCコンパイラプログラミング

大学生のころ読んだと思います。近藤嘉雪さんに私淑していたんですね。

コンパイラが自力で書けるということは、なにか魔法使いになったようなとてもとても私にとって意味があることでした。

億万長者や王様になれるよりも魅力があると感じていたと思います。

これも捨てられない本ですね。

yacc は yet another compiler compilerですね。