ビットごとのORとフラグの追加


16

私は他の人がビットワイズORを使用してフラグを結合する前に見ました:

#define RUN 0x01
#define JUMP 0x02
#define SHOOT 0x04

const byte madPerson = RUN | JUMP | SHOOT;

それも私がやる方法です。

しかし、追加を使用してフラグを結合する(あまり多くない)ものも見ました:

#define RUN 0x01
#define JUMP 0x02
#define SHOOT 0x04

const byte madPerson = RUN + JUMP + SHOOT;

どちらが「読みやすい」のですか?(より多くの人が認識すると思いますか?)それを行う「標準的な」方法は何ですか?あなたはどちらを好みますか?


これはとても質問です。以下のようなものを使用することを検討してください1<<01<<11<<2、など。多くのフラグがあると、読みやすく、保守しやすく、エラーが発生しにくくなります。たとえば、64ビットintの64ビットすべてをパックする場合は、タイプミスを避ける必要1があります:)表現方法も重要です。VS2010の64ビット整数の場合、それはそうだと思います1UI64。間違ったタイプを使用すると、噛みつく可能性があります。
ジョブ

3
@ジョブ:StackOverflowの質問ではありません。読みやすさ、認識可能性、好み、ベストプラクティスについて尋ねているからです。それに対する単一の客観的な答えはありません。ここに属します。
マクニール

回答:


34

ビットごとのOR。

追加は危険です。

盗賊が人であり、怒りの盗賊が話したり撃ったりする盗賊である例を考えてみましょう。後で、すべての盗賊が撃つべきであると決めましたが、怒っている盗賊の定義を忘れており、その射撃フラグを削除しません。

#define PERSON 1 << 0
#define SPEAKS 1 << 1
#define SHOOTS 1 << 2
#define INVINCIBLE 1 << 3
const byte bandit = PERSON | SHOOTS;                    // 00000101
const byte angryBandit_add = bandit + SPEAKS + SHOOTS;  // 00001011 error
const byte angryBandit_or = bandit | SPEAKS | SHOOTS;   // 00000111 ok

angryBandit_addゲームを使用した場合、撃つことも殺すこともできない怒っている盗賊がいるという複雑な論理エラーが発生します。

angryBandit_orあなたが持っている最悪のものを使用した場合は冗長| SHOOTSです。

同様の理由で、ビットごとのNOTは、フラグを削除するための減算よりも安全です。


11

ビット単位ORで意図をより明確に伝える

また、ビット単位のOR より効率的である必要があります


+1確かにORはそれらがフラグであることをより明確にしていると思いますが、効率についてはビット単位の操作が遅い言語があります。たとえば、JavaScriptはすべて数値が64の浮動小数点数です。
Ivo Wetzel

1
OPの例を考えると、1行のORまたは追加がプログラムの実行速度に悪影響を与えるとは思わない。
ティンマン

1
@Greg:特に、この例の計算はコンパイル時に行われるため。:-)
Carson63000

意思を伝えることに加えて、それは... ADA、C#、Javaのを含むがこれらに限定されない多くの言語でこれを見て、かなり一般的です
ケン・ヘンダーソン

2
「すべき」は、このビジネスでは非常に大きな言葉です。今日この問題に遭遇する可能性は非常に低いですが、ビット単位のOR命令を持たないプロセッサで作業したことは非常に明確な思い出があります。1つの命令でビット単位のANDを実行でき、1つの命令でビット単位のXORを実行できますが、ビット単位のORには2つの時間がかかりました。 、もちろんそれを設定します。
ジョンR.ストローム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.