2012-10-12 2 views
5

Ich versuche, eine Enumeration von C++ - Code in C# -Code zu konvertieren, und ich habe Probleme, meinen Kopf darum zu wickeln. Der C++ Code ist:Wiedergabe einiger Bit-Shift-Code von C++ zu C#

enum FOO { 
    FOO_1 = 0, 
    FOO_2, 
    // etc 
} 

#define MASK(x) ((1 << 16) | (x)) 

enum DISP 
{ 
    DISP_1 = MASK(FOO_1), 
    DISP_2 = MASK(FOO_2), 
    // etc 
} 

Was ich nicht verstehe ist, was MASK tut, und wie ich entweder die Funktionalität in C# emulieren, oder verstehen, was es tut und die Enum DISP manuell ohne sie einzustellen.

Ich bin nicht sicher, was ich sage, macht Sinn, aber das ist zu erwarten, wenn ich nicht ganz sicher bin, was ich sehe.

+0

Sie über Verschiebung lesen sollte (<<) und oder (|) Operatoren in C++, so dass Sie verstehen, was los ist. – coredump

+0

werde ich definitiv! – Wint

Antwort

5

MASK(x) eine Anzahl von OR Konstrukte in einer Reihe mit einer x Binärzahl -Ing 10000000000000000 (eines nach links verschoben 16mal).

In C# Sie einen Ausdruck direkt verwenden können, wie folgt aus:

enum FOO { 
    FOO_1 = 0, 
    FOO_2, 
    // etc 
} 

enum DISP 
{ 
    DISP_1 = (1<<16) | (int)(FOO.FOO_1), 
    DISP_2 = (1<<16) | (int)(FOO.FOO_2), 
    // etc 
} 
+0

Das ist genau das, was ich gesucht habe. Danke für das Beispiel! – Wint

2

Ersetzen Sie einfach MASK mit dem, was sie als definiert ist (die << und | Betreiber gibt es in C# zu):

enum DISP 
{ 
    DISP_1 = ((1 << 16) | FOO.FOO_1), 
    DISP_2 = ((1 << 16) | FOO.FOO_2) 
} 

Wenn Sie sich fragen, genau das, was die Verschiebung und oder Operatoren tun, Sie‘ re nimmt den Binärwert von 0000000000000001 und verschiebt es 16 Werte nach links: 1000000000000000. Ein anderes Beispiel, (000001101 << 3) wird 001101000.

Der Operator oder nimmt die alle 1-Werte von den beiden Operanden und setzt den Wert des Ergebnisses zu 1.

Zum Beispiel wird 0001 | 01100111.

Also, nehmen Sie DISP_2:

(0b00000000000000001 << 16) | 0b00000000000000010) 
= (0b10000000000000000 | 0b00000000000000010) 
= (0b10000000000000010) 
= 65538 

(Ich weiß, das 0b Format nicht in C# funktioniert und ist in C nicht Standard, aber es ist sinnvoller binäre Schreibweise zu verwenden anstelle von hexadezimal, einfacher zu sehen, was die Betreiber tun)

7

wenn Sie Verschiebe-Bit, verschiebt es alle 1 und 0 nach links oder rechts durch eine bestimmte Anzahl von Werten.

in Ihrem Fall 1 << 16 erstellt 10000000000000000 im Binärformat. (Ja, das sind 16 Nullen).

Dann nimmt es diese Nummer und verwendet |, die der Bitwise-Operator ist. Also, was auch immer der Integer-Wert der Enumeration ist, wird er bitweise in die von uns bitverschobene Zahl übernommen.

Wenn Sie zum Beispiel MASK(FOO_4) verwenden (was den Literalwert von 3 hat) 3 ist 11 in binär, so würde das Ergebnis 10000000000000011 sein. Dies ist funktional das gleiche wie das Hinzufügen von 65.536 zu jedem Wert.

Jetzt, wenn wir die zweite enum deklarieren, setzen wir die Werte dieser Enum-Werte auf diese seltsame Maskierungsfunktion.

die gleiche Sache zu tun in C# versuchen Sie dies:

enum Foo { //this may not be needed anymore? 
    FOO_1 = 0, FOO_2, ... etc 
} 

enum Disp { //DISP_2 gets the next value ie 65536 + 1, and so forth 
    DISP_1 = 65536, DISP_2, DISP_3, ... etc 
+1

Sie brauchen nicht die + 1, + 2, usw., der Rest wird der Reihe nach von der am Anfang angegebenen zugewiesen. DISP_1 ist der einzige, der einen expliziten Wert zugewiesen bekommt (und FOO_1 muss nicht einmal angegeben werden, da er bei 0 beginnt). – jrajav

+0

Guter Anruf, Sie haben Recht. Ich habe das vergessen. Ähnlich wie PHP – ohmusama

+0

"Much wie C/C++" ist wahrscheinlich relevanter;) – jrajav

0

die numerischen Werte, die DISP_x gleich sind:

DISP_1 == 0x10000 
DISP_2 == 0x10001 
DISP_3 == 0x10002 
... 
0

Die Bit-Shift-Operator arbeitet in C#, aber das definieren Makro doesn‘ t.

Um zu verstehen, was vor sich geht, können Sie die Werte separat berechnen und sie dann in die Enum setzen.

Natürlich wissen Sie, dass | der bitweise OR-Operator ist. Und für den Fall, was der Bediener << tut, ist die binäre nach links verschieben:

1 << 16 = 10000000000000000_2 //those are 16 zeroes and _2 indicates binary 

wiederum:

10000000000000000_2 = 65536 

Das ist das quivalent von mutiplying die Zahl von 2 die Anzahl der Male, die durch der zweite Operand.

1 << 1 = 2 
1 << 2 = 4 
1 << 3 = 8 

Das ist richtig, ist es die Zahl von einer Zweierpotenz multipliziert:

1 << 1 <=> 1 * 2^1 = 2 
1 << 2 <=> 1 * 2^2 = 4 
1 << 3 <=> 1 * 2^3 = 8 

Da nun FOO_1 = 0 dann

DISP_1 = MASK(FOO_1) 
=> 
DISP_1 = ((1 << 16) | (FOO_1)) 
=> 
DISP_1 = (65536 | (FOO_1)) 
=> 
DISP_1 = (65536 | FOO_1) 
=> 
DISP_1 = (65536 | 0) 
=> 
DISP_1 = 65536 

das gleiche für FOO_2 tun, die ich nehmen muss die Wert 1 gibt Ihnen:

DISP_2 = (65536 | FOO_2) 
=> 
DISP_2 = (65536 | 1) 
=> 
DISP_2 = 65537 

, der mit dem die folgenden Arbeiten richtig:

enum FOO 
{ 
    FOO_1 = 0, 
    FOO_2, 
    // etc 
} 

enum DISP 
{ 
    DISP_1 = (1<<16) | (int)(FOO.FOO_1), 
    DISP_2 = (1<<16) | (int)(FOO.FOO_2), 
    // etc 
}