«前の日記(2010年08月04日) 最新 次の日記(2010年08月17日)» 編集

日々をアレコレ


2010年08月05日

ビット演算というのがいまいちなれない

言い訳になるけれど、ウェブアプリとかマシンパワーが潤沢なWindowsアプリばかり開発してきたせいか、組み込み系ではよく使われるビット演算がなんだか慣れない。近々納品予定のソフトでもビット演算を多用しているんだけど、気を抜くと妙な失敗をしてしまっている。今日、テストをしていて一番情けなかったのは、最下位ビットが立っているかどうかの条件分岐をするところで発生したバグ。正しくは次のように書きたかったところ。

if( (hoge & 0x01) == 0x01 )

しかし、僕は次のように書いてた。

if( (hoge && 0x01) == 0x01 )

何がまずいって変数hogeのゼロチェックはここに来るまでにしているので、ここでは条件が常に真となってしまう。なので、思った通りに動作することがなかった。多分、if分だから使うのは&&と条件反射的にキーをたたいてたと思う。もう少し慎重に作らんといかんなー。

本日のツッコミ(全7件) [ツッコミを入れる]
さくらだ (2010年08月18日 00:57)

これは自分もやったことあります。ってか結構な頻度で…(^^;

李徴 (2010年08月19日 00:01)

つ #define BTST(x,p) ((x & p) == p)

李徴 (2010年08月19日 00:05)

あ、イコールイコールがつながって見える… それとxとpは括弧で囲むべきでしたね。

shaga (2010年08月19日 20:22)

個人的には、今回のように確認するビットが1個だけならビット位置を指定して<br>#define CHECK_BITON(x,bit) (((x) & (0x01<<(bit)))!=0)<br>とすることが多いかも。同じように、ビットのオン/オフはこんな感じ。<br>#define SET_BITON(x,bit) ((x) & (0x01<<(bit)))<br>#define SET_BITOFF(x,bit) ((x) | ~(0x01<<(bit)))<br>ビットシフトするけど、どのビットを確認/設定したいのかがソースでよくわかるのが大切だと思ってます。

李徴 (2010年08月19日 23:30)

時間的に許されるならそのほうが分かりやすいでしょうね。アセンブラ(H8)ならそれこそBTST命令1個で済むんですが(笑)。ビットシフトだと実行時間にバラつきが出るんで僕は配列の定数を使います。const UINT8 BIT8[8]={0x01,0x02,0x04(以下略) みたいな。

shaga (2010年08月20日 06:15)

なるほど!その方がいいですね。組み込み系の仕事をしてるはずなのに、その辺の意識とか経験があんまりないのも考え物ですなぁ。

李徴 (2010年08月20日 08:21)

もちろん、固定値ならビットシフトで書いてもコンパイラが計算して即値にしてくれますけどね。


«前の日記(2010年08月04日) 最新 次の日記(2010年08月17日)» 編集