Benutzer mit den meisten Antworten
Integer oder enum bitweise prüfen

Frage
-
Hallo Community,
ich möchte einen Integer nach dessen Wert bitweise abprüfen.
Das geht so nicht.int z = Config.mode | 4; if (Config.mode == 0 || (Config.mode | 4)) { return; }
Der Config.mode kann Werte von 0 bis 7 aufweisen.
Trennung ist die 4, sprich das 3 Bit.
Dann dachte ich, ich nehme ein enum und prüfe es wie folgt.int in enum wandeln.(Possibilities)Config.mode == ((Possibilities)Config.mode & Possibilities.Type1 )
geht auch nicht.Kurzum, ich brauche kurz Hilfe.
Danke für Tipps.Das Ziel ist einfach.
- 0000
- 0001
- 0010
- 0100 Das 4 Bit gilt als Gruppierung, das ist der Grund.
- 0101
- 0110
- 0111
Grüße Markusbyte b1 = 0xCD; // 0xCD = 205 = 11001101 byte b2 = 0x6A; // 0x6A = 106 = 01101010 byte erg1 = (byte)(b1 | 4); // 0xEF = 239 = 11101111 Console.Out.WriteLine("{0:X2}", erg1); [Flags()] public enum Decide : uint { None = 0, Later = 1, Later2 = 2, CheckAdjustment = 4, In2010 = 8 } [Flags()] public enum Possibilities { NotWritten = 0, All = 1, Type1 = 2, Type2 = 3, ToHarddiskCheck = 4, TempAll = 5, TempType1 = 6, TempHarddiskCheck = 7 }
Antworten
-
Hallo Markus, wenn ich das noch einmal zusammenfasse,...
ich lese aus der App.config den Integerwert z.B. 3.
Möchte nun prüfen
0000
0001
0010
0100 Das 4 Bit gilt als Gruppierung, das ist der Grund.
0101
0110
0111
ist der Wert oberhalb oder unterhalb der 'sogenannten' Gruppe.
Also wenn der Configwert 7 ist, teste bitweise mit der 4, weiß ich, ich bin unterhalb.
public enum Possibilities { NotWritten = 0, All = 1, Type1 = 2, Type2 = 3, ToHarddiskCheck = 4, // obere oder untere Hälfte TempAll = 5, TempType1 = 6, TempHarddiskCheck = 7 }
- ... Ich will einfach obere/untere Hälfte(Gruppe) prüfen, ...
... willst du also scheinbar nur wissen, ob dein eingelesener Config-Wert kleiner, gleich oder größer 4 ist.
Dann weißt du, ob du oberhalb, auf dem Punkt oder unterhalb bist.
Also, wozu eigentlich die ganze Bit-Testerei?
bool obererTeil = (Possibilities)ConfigMode < Possibilities.ToHarddiskCheck; bool Grenze = (Possibilities)ConfigMode == Possibilities.ToHarddiskCheck; bool untereTeil = (Possibilities)ConfigMode > Possibilities.ToHarddiskCheck;
Gruß
- Als Antwort markiert MarkusMayer Sonntag, 12. Juni 2016 13:34
-
Hallo,
um zu testen ob ein Bit gesetzt ist, verwendet man ein binäres Und "&" - kein Oder "|", denn das setzt den Wert, und wäre immer wahr, also
if ((Config.mode == 0) || ((Config.mode & 4) != 0)) { return ; }
wobei man je nach Geschmack auch auf == 4 testen könnte.
Im übrigen erlauben Enumerationen über das Flags Attribut mehrere Bits zusammen zu fassen / zu testen, siehe auch: http://stackoverflow.com/questions/8447/what-does-the-flags-enum-attribute-mean-in-c.
Gruß Elmar
- Als Antwort markiert MarkusMayer Montag, 13. Juni 2016 16:30
-
Hallo Markus,
du kannst mit "geflagter" Enum genau dasselbe machen wie mit den anderen Bitoperationen. Du musst nur daran denken, dass die Prüfung auf das MSB deine Enum nur dann in zwei Hälften teilt (zur oberen Hälfte gehörend...), wenn die "Bitbreite" ausgeschöpft wird.
In deinem Fall hast du quasi eine 3-Bit Zahl, dezimal 0 bis 7 oder binär 000 bis 111. Würdest du jetzt die Enum um eine Position erweitern, also den Wert 8... einführen, schlägt dein Konzept fehl. Du hättest dann quasi eine 4-Bit breite Zahl, das MSB teilt aber nicht mehr die Gruppe, da die Werte 9-15 fehlen.
Also, bei der Frage die sich dir stellt, läuft ja alles eigentlich auf "ist größer, gleich oder keiner als" hinaus, und dafür gibt es die schlichten Vergleichsoperatoren.
Ich meine, die "geflagte" Enum macht Sinn, falls mehrere Optionen zeitgleich gesetzt sein können und/oder du gezielt bestimmte Kombinationen abfragen möchtest. Dann müsstest du die Enumeration allerdings etwas anders aufbauen, da jede Kombination eine eindeutige Summe erfordert und deine Werte könnten statt 0,1,...,7 dann 0,1,2,4,8,16,32,64 lauten.
Als Ergänzung: mit..
[Flags] public enum PBF { NotWritten = 0, All = 1, Type1 = 2, Type2 = 3, ToHarddiskCheck = 4, TempAll = 5, TempType1 = 6, TempHarddiskCheck = 7, UngünstigJetzt = 8 // <--- }
und
for ( ConfigMode = 0 ; ConfigMode < 9 ; ConfigMode++ ) { Console.WriteLine($"HasFlag: {((PBF)ConfigMode).HasFlag(PBF.ToHarddiskCheck)}"); } Console.ReadKey();
lässt sich das, was ich meine, vielleicht verdeutlichen.
Gruß
- Als Antwort markiert MarkusMayer Dienstag, 14. Juni 2016 16:24
Alle Antworten
-
Hi Markus,
so richtig verstanden habe ich nicht, was Du ermitteln willst, deshalb hier mal eine Anregung:byte b1 = 0xCD; // 0xCD = 205 = 11001101 byte b2 = 0x6A; // 0x6A = 106 = 01101010 var res1 = b1 | b2; // bitweises Oder var res2 = b1 & b2; // bitweises Und var res3 = b1 ^ b2; // bitweises exclusives Oder Console.WriteLine(res1); Console.WriteLine(res2); Console.WriteLine(res3); Console.WriteLine($"Bit 04 in b1 ein: {(b1 & 4) != 0}"); Console.WriteLine($"Bit 04 in b2 ein: {(b2 & 4) != 0}");
--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks
Kommas richtig setzen! Leben retten!
Wir essen Opa.
Wir essen, Opa. -
Hallo Peter,
int z = Config.mode | 4; if (Config.mode == 0 || (Config.mode | 4)) { return; }
ich lese aus der App.config den Integerwert z.B. 3.
Möchte nun prüfen
0000
- 0001
- 0010
- 0100 Das 4 Bit gilt als Gruppierung, das ist der Grund.
- 0101
- 0110
- 0111
ist der Wert oberhalb oder unterhalb der 'sogenannten' Gruppe.
Also wenn der Configwert 7 ist, teste bitweise mit der 4, weiß ich, ich bin unterhalb.
Wie macht man das in C#? Klar?
If geht nicht, kommt immer kann nicht auf bool prüfen. In C++ geht es wie oben beschrieben.
Grüße Markus
-
Hallo,
vielleicht hilft dies weiter:
int ConfigMode = Convert.ToInt32("1110", 2); string bin = Convert.ToString(ConfigMode, 2); for ( int position = 0 ; position < bin.Length ; position++){ bool gesetzt = (ConfigMode & (1 << position)) > 0; Console.WriteLine($"Bit an Position {position} in {bin} ist gesetzt: {gesetzt}"); } Console.ReadKey();
Gruß
-
Hi Markus,
das geht in C# genau so mit dem Unterschied, dass in C++ ein Byte mit 0-Bits als false gewertet wird. Das ist in C# zu konvertieren:if (Config.mode == 0 || (Config.mode | 4) == 0 )
--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks
Kommas richtig setzen! Leben retten!
Wir essen Opa.
Wir essen, Opa. -
Hallo Markus,
so lang und aufwändig ist das nun nicht, oder?
Also, wenn du testen willst, ob ConfigMode 0 ist oder in ConfigMode das dritte Bit gesetzt ist, so habe ich die Frage richtig verstanden?
ConfigMode == 0 || (ConfigMode & (1 << position)) > 0
So kannst du die Position angeben, du kannst natürlich statt 1 << 2 (für die dritte Position) auch, wie Peter gezeigt hat, direkt 4 angeben, also
ConfigMode == 0 || (ConfigMode & 4) > 0
Gruß
- Bearbeitet K. Pater Freitag, 10. Juni 2016 21:09
-
Hi Markus,
ich vermute, dass Dum mit dem Code Probleme bekommen wirst:(Config.mode | Possibilities.ToHarddiskCheck ) == 1
Da hier ein ODER ausgeführt wird, ist das Ergebnis wahr, wenn entweder Config.mode an irgendeiner Stelle ein gesetztes Bit hat oder, falls Config.mode kein gesetztes Bit hat, Possibilities.ToHarddiskCheck ein gesetztes Bit hat. Aus Deinen Ausführungen vermute ich, dass Du ein UND an dieser Stelle benötigst.--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks
Kommas richtig setzen! Leben retten!
Wir essen Opa.
Wir essen, Opa. -
Hallo Markus, wenn ich das noch einmal zusammenfasse,...
ich lese aus der App.config den Integerwert z.B. 3.
Möchte nun prüfen
0000
0001
0010
0100 Das 4 Bit gilt als Gruppierung, das ist der Grund.
0101
0110
0111
ist der Wert oberhalb oder unterhalb der 'sogenannten' Gruppe.
Also wenn der Configwert 7 ist, teste bitweise mit der 4, weiß ich, ich bin unterhalb.
public enum Possibilities { NotWritten = 0, All = 1, Type1 = 2, Type2 = 3, ToHarddiskCheck = 4, // obere oder untere Hälfte TempAll = 5, TempType1 = 6, TempHarddiskCheck = 7 }
- ... Ich will einfach obere/untere Hälfte(Gruppe) prüfen, ...
... willst du also scheinbar nur wissen, ob dein eingelesener Config-Wert kleiner, gleich oder größer 4 ist.
Dann weißt du, ob du oberhalb, auf dem Punkt oder unterhalb bist.
Also, wozu eigentlich die ganze Bit-Testerei?
bool obererTeil = (Possibilities)ConfigMode < Possibilities.ToHarddiskCheck; bool Grenze = (Possibilities)ConfigMode == Possibilities.ToHarddiskCheck; bool untereTeil = (Possibilities)ConfigMode > Possibilities.ToHarddiskCheck;
Gruß
- Als Antwort markiert MarkusMayer Sonntag, 12. Juni 2016 13:34
-
Also, wozu eigentlich die ganze Bit-Testerei?
bool obererTeil = (Possibilities)ConfigMode < Possibilities.ToHarddiskCheck; bool Grenze = (Possibilities)ConfigMode == Possibilities.ToHarddiskCheck; bool untereTeil = (Possibilities)ConfigMode > Possibilities.ToHarddiskCheck;
Hallo K. Pater,
ja Du hast Recht.
[Flags()] public enum Possibilities { NotWritten = 0, All = 1, Type1 = 2, Type2 = 3, ToHarddiskCheck = 4, // obere oder untere Hälfte TempAll = 5, TempType1 = 6, TempHarddiskCheck = 7 }
so würde es auch gehen, ohne Bittesterei. Man merkt auch hier, so einfach ist das nicht;-)
Das Problem ist so gelöst. Ich lasse den Thread noch offen, rein interessehalber, vielleicht weiß jemand noch was, gerne mit Bittesterei, Bitschieberei, vielleicht kann man es mal brauchen.
Wie gesagt Danke an Allen mal.
int in enum, einfach casten - beantwortet
das Ziel - beantwortet
Vielleicht noch wo liegt der Unterschied, wenn ich bei enum Flags davorstelle.
Geht das ohne dann gar nicht, bitweise prüfen?
Grüße Markus
-
Hi Klaus,
ich prüfe da nix. Das war die Übersetzung von C++ nach C# der Anweisung aus dem Post vom Markus, welches inzwischen gelöscht ist. Der Sinn dieser Logik erschließt sich mir nicht. Ich weiß auch nicht, was Markus da im C++-Programm gemacht hatte.--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks
Kommas richtig setzen! Leben retten!
Wir essen Opa.
Wir essen, Opa. -
Hallo Zusammen,
bool obererTeil = (Possibilities)ConfigMode < Possibilities.ToHarddiskCheck; bool Grenze = (Possibilities)ConfigMode == Possibilities.ToHarddiskCheck; bool untereTeil = (Possibilities)ConfigMode > Possibilities.ToHarddiskCheck;
ich denke das ist die Lösung. Alternativ wäre es noch nett, wenn Ihr mir ein Beispiel mit den Flag parat hättet.
Um nicht für Verwirrung zu sorgen, habe ich ein Posting gelöscht.
Viele Grüße Markus und DANKE.
-
ich prüfe da nix. Das war die Übersetzung von C++ nach C# der Anweisung aus dem Post vom Markus, welches inzwischen gelöscht ist. Der Sinn dieser Logik erschließt sich mir nicht. Ich weiß auch nicht, was Markus da im C++-Programm gemacht hatte.
Hallo Peter,
wie Klaus erkannte lediglich eine Grenze oben und unten -- 4 ist das Entscheidungsbit.
Grüße Markus
int z = Config.mode | 4; if (Config.mode == 0 || (Config.mode | 4)) { return; }
-
Hi Markus
int z = Config.mode | 4; if (Config.mode == 0 || (Config.mode | 4)) { return; }
Mit dem nachfolgenden Code kannst Du den Unsinn dieser Anweisung darstellen:
using System; namespace ConsoleApplication8 { class Program { static void Main(string[] args) { for (byte i = 0; i < 15; i++) { Config.mode = i; Console.WriteLine($"{i} {TestSub()}"); } Console.ReadKey(); } private static bool TestSub() { if (Config.mode == 0 || (Config.mode | 4) != 0) { return true; } return false; } internal static class Config { internal static byte mode { get; set; } } } }
--
Viele Grüsse
Peter Fleischer (MVP, Partner)
Meine Homepage mit Tipps und Tricks
Kommas richtig setzen! Leben retten!
Wir essen Opa.
Wir essen, Opa. -
Hallo,
um zu testen ob ein Bit gesetzt ist, verwendet man ein binäres Und "&" - kein Oder "|", denn das setzt den Wert, und wäre immer wahr, also
if ((Config.mode == 0) || ((Config.mode & 4) != 0)) { return ; }
wobei man je nach Geschmack auch auf == 4 testen könnte.
Im übrigen erlauben Enumerationen über das Flags Attribut mehrere Bits zusammen zu fassen / zu testen, siehe auch: http://stackoverflow.com/questions/8447/what-does-the-flags-enum-attribute-mean-in-c.
Gruß Elmar
- Als Antwort markiert MarkusMayer Montag, 13. Juni 2016 16:30
-
Hallo,
wann nehme ich Flags, wann nicht.
Nur als Hilfe fürs debuggen? Das Ergebnis ist das Gleiche.BTE.Possibilities test; test = BTE.Possibilities.TempHarddiskCheck; b1 = (test == BTE.Possibilities.NotWritten); b2 = ((test & BTE.Possibilities.ToHarddiskCheck) == BTE.Possibilities.ToHarddiskCheck); // [Flags()] public enum Possibilities { NotWritten = 0, All = 1, Type1 = 2, Type2 = 3, ToHarddiskCheck = 4, // obere oder untere Hälfte TempAll = 5, TempType1 = 6, TempHarddiskCheck = 7 }
Mit - sehr schön zu sehen.
Ohne mit gleichem Ergebnis.
Wenn der Mode 5 aufweist, ist es mit Flag All | ToHarddiskCheck
ohne Flag TempAllGrüße Markus -
Hallo Markus,
du kannst mit "geflagter" Enum genau dasselbe machen wie mit den anderen Bitoperationen. Du musst nur daran denken, dass die Prüfung auf das MSB deine Enum nur dann in zwei Hälften teilt (zur oberen Hälfte gehörend...), wenn die "Bitbreite" ausgeschöpft wird.
In deinem Fall hast du quasi eine 3-Bit Zahl, dezimal 0 bis 7 oder binär 000 bis 111. Würdest du jetzt die Enum um eine Position erweitern, also den Wert 8... einführen, schlägt dein Konzept fehl. Du hättest dann quasi eine 4-Bit breite Zahl, das MSB teilt aber nicht mehr die Gruppe, da die Werte 9-15 fehlen.
Also, bei der Frage die sich dir stellt, läuft ja alles eigentlich auf "ist größer, gleich oder keiner als" hinaus, und dafür gibt es die schlichten Vergleichsoperatoren.
Ich meine, die "geflagte" Enum macht Sinn, falls mehrere Optionen zeitgleich gesetzt sein können und/oder du gezielt bestimmte Kombinationen abfragen möchtest. Dann müsstest du die Enumeration allerdings etwas anders aufbauen, da jede Kombination eine eindeutige Summe erfordert und deine Werte könnten statt 0,1,...,7 dann 0,1,2,4,8,16,32,64 lauten.
Als Ergänzung: mit..
[Flags] public enum PBF { NotWritten = 0, All = 1, Type1 = 2, Type2 = 3, ToHarddiskCheck = 4, TempAll = 5, TempType1 = 6, TempHarddiskCheck = 7, UngünstigJetzt = 8 // <--- }
und
for ( ConfigMode = 0 ; ConfigMode < 9 ; ConfigMode++ ) { Console.WriteLine($"HasFlag: {((PBF)ConfigMode).HasFlag(PBF.ToHarddiskCheck)}"); } Console.ReadKey();
lässt sich das, was ich meine, vielleicht verdeutlichen.
Gruß
- Als Antwort markiert MarkusMayer Dienstag, 14. Juni 2016 16:24