Logo

employee blog社員ブログ

奇数偶数判定どちらが出てくるか?

さて、私のブログ当番が回ってきました。どうもYuEです。
今回はエンジニアらしくプログラムのお話をしていきます。

プログラミングは一種のセンスあり、なしを問われる世界と言われています。
どういうときにその差が出るかと言われると、例えばプログラミングの練習問題で奇数偶数を判定するプログラムを作成してください、という問題が出たとします。
言語をPHPとして考えたときに、すぐに思いつくのは下記のプログラムかと思います。

---------------------------------------
◆パターンA
対象の数字($num)を2で割ることとで余りを計算。
余りが無ければ偶数、あれば奇数になる。

if ($num % 2 == 0) {
echo "偶数です";
} else {
echo "奇数です";
}
---------------------------------------

大抵はパターンAで組むことが多いですが、この問題では別解としてパターンBが存在します。
それがこれ。

---------------------------------------
◆パターンB
ビット演算子の考え方を利用して計算。
ビットが2進数であることを利用して2進数化した末尾が1であれば奇数。

if($num & 1) {
echo "奇数です";
} else {
echo "偶数です";
}
---------------------------------------

……パターンBは難しいですよね!
でも、2進数で10までの数値を考えてみてください。

★2進数表記で1から10まで表示
0001  //10進数では1
0010  //10進数では2
0011  //10進数では3
0100  //10進数では4
0101  //10進数では5
0110  //10進数では6
0111  //10進数では7
1000  //10進数では8
1001  //10進数では9
1010  //10進数では10

よくみると下一桁が奇数の時は必ず1になります。
ビット演算の理論を使ったのがパターンBです。

2進数は0と1しか存在しません。
つまり、"1"とビット演算を行う相手の数値の最下位ビットが"1"であるならば、奇数です。
最下位ビットが"0"の時は、偶数です。

もっと平たく言うと、
判定する値が奇数なら演算結果は1
判定する値が偶数なら演算結果は0
です。

PHPでは整数型から論理型に変換するときに値が0のときはFalse
それ以外はTrueにするという法則があるのでパターンBの計算が成り立つことになります。

うん、やっぱり難しいですね(笑)
正直、私も自分で組むならパターンAです。
しかし、処理速度としてはパターンBのほうが、よりシステムが理解しやすいので早くなります。
だけど、他人が組んだプログラムを読むならパターンAのほうが解読しやすい。
個人的にはパターンBをコメントなしで組まれたら一瞬戸惑うかもしれないのでパターンAがいいな。可読性は大事。

保守性や生産性も左右するので人間が読みやすいほうが良いと思う反面、ゲームのように速さを追求するシステムを構築する場合はパターンBを推奨する人も一定数いるので何とも言えないところですね。
プログラムは結果は同じでも、そこに至るまでのプロセスは人によって異なる、というお話でした。