it-swarm.com.de

Warum werden Flaggenummern normalerweise mit hexadezimalen Werten definiert?

Oft sehe ich Flag-Enum-Deklarationen, die hexadezimale Werte verwenden. Beispielsweise:

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

Wenn ich eine Aufzählung deklariere, deklariere ich sie normalerweise so:

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

Gibt es einen Grund oder eine Begründung dafür, warum manche den Wert eher hexadezimal als dezimal schreiben? So wie ich es sehe, ist es leichter, verwirrt zu werden, wenn Hex-Werte verwendet werden und versehentlich Flag5 = 0x16 anstatt Flag5 = 0x10.

112
Adi Lester

Rationales mag unterschiedlich sein, aber ein Vorteil, den ich sehe, ist, dass hexadezimal erinnert: "Okay, wir haben es nicht mehr mit Zahlen in der von Menschen erfundenen Welt der Basis zehn zu tun. Wir haben es mit Bits zu tun - der Welt der Maschine - und wir werden nach seinen Regeln spielen. " Hexadezimal wird nur selten verwendet, wenn Sie sich mit relativ einfachen Themen befassen, bei denen das Speicherlayout von Daten von Bedeutung ist. Die Verwendung weist darauf hin, dass dies die Situation ist, in der wir uns gerade befinden.

Ich bin mir auch nicht sicher über C #, aber ich weiß, dass in C x << y ist eine gültige Konstante für die Kompilierungszeit. Die Verwendung von Bitverschiebungen scheint am klarsten zu sein:

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

Es macht es einfach zu sehen, dass dies binär Flags sind.

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

Das Fortschreiten macht es jedoch noch deutlicher:

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

Ich denke es liegt nur daran, dass die Sequenz immer 1,2,4,8 ist und dann eine 0 addiert.
Wie du siehst:

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

und so weiter, solange Sie sich an die Sequenz 1-2-4-8 erinnern, können Sie alle nachfolgenden Flags erstellen, ohne sich an die Potenzen von 2 erinnern zu müssen

34
VRonin

Weil [Flags] bedeutet, dass die Aufzählung wirklich ein Bitfeld ist. Mit [Flags] Sie können das bitweise UND (&) und OR (|) Operatoren, um die Flags zu kombinieren. Bei solchen Binärwerten ist es fast immer klarer, hexadezimale Werte zu verwenden. Genau aus diesem Grund verwenden wir hexadezimal . Jedes Hex-Zeichen entspricht genau einem Nibble (vier Bits). Mit dezimaler Angabe gilt diese 1-zu-4-Zuordnung nicht.

13

Weil es eine mechanische, einfache Möglichkeit gibt, eine Zweierpotenz in hex zu verdoppeln. Im Dezimalformat ist dies schwierig. Es erfordert lange Multiplikation in Ihrem Kopf. In hex ist es eine einfache Änderung. Sie können dies bis zu 1UL << 63 Ausführen, was Sie nicht in Dezimalzahlen tun können.

4
usr

Weil es für Menschen einfacher ist zu folgen, wo die Bits in der Flagge sind. Jede hexadezimale Ziffer kann in eine 4-Bit-Binärzahl passen.

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

... and so on

0xF = 1111

Normalerweise möchten Sie, dass sich Ihre Flags nicht mit Bits überschneiden. Die einfachste Möglichkeit, dies zu tun und zu visualisieren, besteht darin, Ihre Flags mit hexadezimalen Werten zu deklarieren.

Wenn Sie also Flags mit 16 Bit benötigen, verwenden Sie 4-stellige Hexadezimalwerte. Auf diese Weise können Sie fehlerhafte Werte vermeiden:

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