web-dev-qa-db-ja.com

フラグ列挙が通常16進値で定義されている理由

多くの場合、16進値を使用するフラグ列挙宣言が表示されます。例えば:

[Flags]
public enum MyEnum
{
    None  = 0x0,
    Flag1 = 0x1,
    Flag2 = 0x2,
    Flag3 = 0x4,
    Flag4 = 0x8,
    Flag5 = 0x10
}

Enumを宣言するとき、通常は次のように宣言します。

[Flags]
public enum MyEnum
{
    None  = 0,
    Flag1 = 1,
    Flag2 = 2,
    Flag3 = 4,
    Flag4 = 8,
    Flag5 = 16
}

一部の人々が10進数ではなく16進数で値を書き込むことを選択する理由または理由はありますか?私の見方では、16進値を使用しているときに混乱しやすく、誤ってFlag5 = 0x16 の代わりに Flag5 = 0x10

112
Adi Lester

論理的根拠は異なるかもしれませんが、私が見る利点は、16進数が次のことを思い出させることです。 「そのルールで遊ぶつもりです。」データのメモリレイアウトが重要な比較的低レベルのトピックを処理する場合を除き、16進数はほとんど使用されません。それを使用することは、それが現在の状況であるという事実を示唆しています。

また、C#についてはわかりませんが、C x << yは有効なコンパイル時定数です。ビットシフトを使用することが最も明確なようです。

[Flags]
public enum MyEnum
{
    None  = 0,
    Flag1 = 1 << 0,
    Flag2 = 1 << 1,
    Flag3 = 1 << 2,
    Flag4 = 1 << 3,
    Flag5 = 1 << 4
}
172
SelectricSimian

これらがbinaryフラグであることを簡単に確認できます。

None  = 0x0,  // == 00000
Flag1 = 0x1,  // == 00001
Flag2 = 0x2,  // == 00010
Flag3 = 0x4,  // == 00100
Flag4 = 0x8,  // == 01000
Flag5 = 0x10  // == 10000

progressionによりさらに明確になりますが:

Flag6 = 0x20  // == 00100000
Flag7 = 0x40  // == 01000000
Flag8 = 0x80  // == 10000000
42
Oded

シーケンスが常に1、2、4、8であり、0を追加したからだと思います。
ご覧のように:

0x1 = 1 
0x2 = 2
0x4 = 4
0x8 = 8
0x10 = 16
0x20 = 32
0x40 = 64
0x80 = 128
0x100 = 256
0x200 = 512
0x400 = 1024
0x800 = 2048

といったように、シーケンス1-2-4-8を覚えている限り、2のべき乗を覚えなくても後続のすべてのフラグを作成できます。

34
VRonin

なぜなら[Flags]は、enumが実際に bitfield であることを意味します。 [Flags]ビット単位のAND(&)およびOR(|)フラグを結合する演算子。このようなバイナリ値を扱う場合、16進値を使用する方がほとんど常に明確です。これが、最初に hexadecimal を使用するまさにその理由です。各16進文字は、exactly1ニブル(4ビット)に対応します。 10進数では、この1対4マッピングは当てはまりません。

13

なぜなら、2のべき乗を16進数で2倍にするための機械的で簡単な方法があるからです。 10進数では、これは困難です。頭の中で長い掛け算が必要です。 16進数では、単純な変更です。これは、1UL << 63まで実行できますが、10進数ではできません。

4
usr

なぜなら、ビットが旗の中にある人間にとっては従うのが簡単だからです。各16進数は4ビットのバイナリに適合できます。

0x0 = 0000
0x1 = 0001
0x2 = 0010
0x3 = 0011

... and so on

0xF = 1111

通常、フラグをビットにオーバーラップさせたくないので、フラグを宣言するために16進値を使用するのが最も簡単な方法です。

したがって、16ビットのフラグが必要な場合は、4桁の16進値を使用します。これにより、誤った値を回避できます。

0x0001 //= 1 = 000000000000 0001
0x0002 //= 2 = 000000000000 0010
0x0004 //= 4 = 000000000000 0100
0x0008 //= 8 = 000000000000 1000
...
0x0010 //= 16 = 0000 0000 0001 0000
0x0020 //= 32 = 0000 0000 0010 0000
...
0x8000 //= 32768 = 1000 0000 0000 0000
2
Only You