論理演算子

このページは、 教科書 K&R2 などで一通りC言語について学んだ人を対象としています。 特に、同書 §2.9 Bitwise Operators は必須です。

おさらい

x, mask を同じ型の符号なし整数型変数とし、 mask は(下から) n ビット目だけが 1 で残りは 0 とします。 すると、x & mask は x の n ビット目が 0 なら零, 1 なら非零となるので、 こうやって x の n ビット目が 0 か 1 かを判定できるのでした。

また、x, a を同じ型の符号なし整数型変数とするとき、 x = x | a とすると x のビットのうち、a で 1 となっているものは 1 になるのでした。 (a で 0 となっているものはそのまま。)

オプション課題

関数 unsigned int add(unsigned int x, unsigned int y) で、 加減乗除の演算を使わずに x + y の値を返すものを書いてください。

ヒント: 小学校で習った十進の足し算のように、下の桁 --- いまの場合は二進なので下のビット --- から計算してゆきます。 まず、変数 mask に 1 を代入すると x & mask, y & mask が x, y の一番下のビットになります。 結果 sum の一番下のビットは、 これらから and や or や not で計算できますので、 論理演算子を使って求められます。 一番下の桁から次の桁へのくり上がりの有無も同様です。 次に mask を左へ1桁シフトすると、 x & mask, y & mask は x, y の下から二番目のビットになります。 これらと、一番下の桁からのくり上がりの三つから、 結果 sum の下から二番目のビットと、 下から二番目の桁から三番目の桁へのくり上がりを論理演算子で求める……、 とくり返してゆきます。

適当な main() もつけて、 そのまますぐにコンパイルして試せるようにしてメールで送ってください。 main() ではユーザに二つの数を入力させて add() と + の二通りの計算結果を並べて示すとか、 大量に乱数を発生させて add() と + の計算結果を比べ、 エラーが一度もなければ OK, 一度でもあれば NO と出力する、などが考えられます。 オプション課題なので、期限は特に決めません。 また、メールの Subject は適当につけて、 メール本文でどのオプション課題に対するレポートなのか説明してください。

※ この課題の解答となるプログラムを私は以前に書いたことがあるが、 上の説明は記憶に基づいて書いたものである。 よって、誤りがある可能性があるが、 その場合は適当に修正しつつ取り組んでみてほしい。


岩瀬順一