12

boolビットを表す3 つの値があります。フォームに整数が必要です

true true true = 7
false true false = 2

私は持っている

int val = 4*boolVal1 + 2*boolVal2 + boolVal3;

もっと簡単な別の方法はありますか?

4

4 に答える 4

27

乗算と加算の代わりにビット単位の演算子を使用する方がわかりやすいかもしれません。

int val = (boolVal1 << 2) | (boolVal2 << 1) | boolVal3; 
于 2012-07-03T12:36:52.363 に答える
5

または、ホーナーの方法を使用できます。

int val = (((boolVal1 << 1) | boolVal2) << 1) | boolVal3.

これにより、他のすべての係数を変更することなく、ステートメントの途中で変数を追加または削除することも容易になります。

ただし、これは読者には少しわかりにくいかもしれません。

于 2012-07-03T12:53:12.527 に答える
4

乗算とビットシフト以外に、列挙型を使用して関係を文書化することもできます。通常、努力する価値はありませんが、完全を期すために...

enum Encoding
{ 
    Flag3 = 1,      NotFlag3 = 0,
    Flag2 = 1 << 1, NotFlag2 = 0,
    Flag1 = 1 << 2, NotFlag1 = 0
};

int val = (boolVal1 ? Flag1 : NotFlag1) |
          (boolVal2 ? Flag2 : NotFlag2) |
          (boolVal3 ? Flag3 : NotFlag3);

なぜこれを気にするのですか?これはもう少し一般的であるため、実際の値を使用して配布される可能性のあるコードに触れることなく、後でエンコーディング値を変更できる可能性があります (たとえば、一部のファイルまたはネットワークの形式と比較して少し省略したことに気付いた場合)。解析する必要のあるデータを 1 か所に追加して再コンパイルできます)。もちろん、とにかく単一のエンコード/デコード機能を提供する方がよいでしょう。新しいフラグを追加する場合は、それでも必要になります。

Flag1 と NotFlag1 を持つことは無意味に思えるかもしれませんが、Sticky と Floating、または Male と Female などの相互に排他的な値がある場合が多く、クライアントに Floating を !Sticky または Female として確認するよう強制する特別な理由はありません。として!男性など..

于 2012-07-03T12:45:17.037 に答える
2

エンディアンがわかっている場合は、実装定義の動作とビットセット、リトル エンディアン バージョンを使用することもできます。

union foo {
        unsigned int the_int;
        struct {
                unsigned int bit3:1
                unsigned int bit2:1
                unsigned int bit1:1
        };
};

次に、それらを設定します。

foo.bit1 = true;
foo.bit2 = false;
foo.bit3 = true;

そして読むために:

foo.the_int;

ビッグ エンディアン バージョンでは、ビットが逆になり、多くのパディング (unsigned int幅が 32 ビットの場合は 29 ビット) が先頭にあります。

于 2012-07-03T13:49:49.433 に答える