Verwenden Sie Konstanten und geben Sie ihnen Eigennamen. Dann sollte die Tatsache, dass Sie sie dezimal schreiben müssen, keine Rolle spielen. Persönlich würde ich lieber lesen if (a == MaskForModemIOEnabled)alsif (a == 0b100101)
Beides sehr gute Ratschläge, außer bei der Definition der genannten Bitfelder, bei denen diese benannten konstanten Definitionen mit einem binären Literal leichter zu lesen und zu schreiben sind. [Flags] enum Menge {Keine = 0, Eins = 1, Einige = 0b10, Meist = 0b100, Alle = 0b111}
brianary
1
Für Roslyn ist die Unterstützung von binären Literalen geplant .
Joe White
Es wird in C # 6.0 immer noch nicht unterstützt, oder? Ich kann keine binären Literale in vs2015 verwenden: /
anhoppe
Antworten:
145
C # 7.0 unterstützt binäre Literale (und optionale Zifferntrennzeichen über Unterstriche).
Süss! Funktioniert hervorragend in VS2017 / C # 7.
STLDev
1
Es ist hilfreich, sich daran zu erinnern, dass die binären Literale von C # Big-Endian sind, aber auf x86-Ganzzahlen Little-Endian sind und daher Int16 = 0b0010_0110_0000_0011als { 0b0000_0011, 0b0010_0110 }- verwirrend gespeichert werden .
Dai
1
@Dai das ist nicht anders als Hex-Literale. Mit anderen Worten, alle Konstanten sind Big Endian, aber Little Endian auf Intel / AMD und den meisten ARMs gespeichert. 0xDEADBEEFwird gespeichert als0xEF 0xBE 0xAD 0xDE
Cole Johnson
168
Aktualisieren
C # 7.0 hat jetzt binäre Literale, was großartig ist.
Da sich das Thema anscheinend darauf konzentriert hat, bitbasierte Flag-Werte in Aufzählungen zu deklarieren, hielt ich es für sinnvoll, auf einen praktischen Trick für diese Art von Dingen hinzuweisen. Mit dem Linksverschiebungsoperator ( <<) können Sie ein bisschen an eine bestimmte Binärposition drücken. Kombinieren Sie dies mit der Möglichkeit, Enum-Werte in Bezug auf andere Werte in derselben Klasse zu deklarieren, und Sie haben eine sehr einfach zu lesende deklarative Syntax für Bit-Flag-Enums.
@ColeJohnson: Viele Entwickler bevorzugen das. Ich bin nicht so gut darin, Hex in meinem Kopf zu konvertieren wie manche Entwickler, und manchmal ist es am besten, auf den kleinsten gemeinsamen Nenner zu achten.
StriplingWarrior
2
Ich denke, dies ist der effektivste Weg, da Aufzählungen als Konstanten erstellt werden. Mit dem optionalen Attribut [Flags] können sie in bitweisen Operationen verwendet werden (nicht direkt mit der Frage verbunden, aber besonders nützlich bei der Beschreibung von Binärliteralen). Eine weitere interessante Möglichkeit besteht darin, den Aufzählungstyp als integrierten Typ zu erzwingen (in diesem Beispiel fügen Sie nach 'Tagen' ': Byte' hinzu). siehe eingebaute Typen in bit.ly/MKv42E
Caligari
Das ist eigentlich sehr einfach zu lesen, obwohl das Deklarieren einer 0-Flagge in einer Aufzählung ziemlich schlecht ist
MikeT
5
@MikeT: Können Sie diesen letzten Gedanken näher erläutern (oder einen ausführlichen Link bereitstellen)? Ich deklariere oft Aufzählungen, die mit "1" beginnen, weil ich erkennen und schnell ausfallen möchte, wenn ein Wert einfach nie initialisiert wurde. Es gibt jedoch Situationen, in denen ein Standardwert tatsächlich Sinn macht, und ich würde denken, dass das Hinzufügen eines Namens für diesen Wert nichts Falsches wäre.
StriplingWarrior
3
@MikeT Von ca1008 : "Wenn eine Aufzählung, auf die das FlagsAttribute angewendet wird, ein Element mit dem Wert Null definiert, sollte der Name 'Keine' lauten, um anzuzeigen, dass in der Aufzählung keine Werte festgelegt wurden." Es ist also durchaus gültig, es als Standardwert hinzuzufügen, wenn es "Keine" heißt. Insgesamt erscheint es mir nur sauberer, wenn der Wert in einem standardmäßig initialisierten Feld tatsächlich einen Namen zum Anzeigen hat.
Nyerguds
115
Ich fürchte, nur Ganzzahl und Hex direkt (ECMA 334v4):
9.4.4.2 Integer-Literale Integer-Literale werden verwendet, um Werte vom Typ int, uint, long und ulong zu schreiben. Ganzzahlige Literale haben zwei mögliche Formen: dezimal und hexadezimal.
Als Aktualisierung dieser Antwort mit den neuesten modernen Informationen (Juli 2014); C # 6.0 führt binäre Literale ein. Siehe meine aktualisierte Antwort wayyyyyy unten ...
BTownTKD
1
@BTownTKD Ihre Antwort ist eigentlich ganz oben :) da es die akzeptierte Antwort ist.
RBT
25
Neben der Antwort von @ StriplingWarrior zu Bit-Flags in Aufzählungen gibt es eine einfache Konvention, die Sie hexadezimal verwenden können, um durch die Bitverschiebungen nach oben zu zählen. Verwenden Sie die Sequenz 1-2-4-8, verschieben Sie eine Spalte nach links und wiederholen Sie den Vorgang.
Scannen Sie ab der rechten Spalte nach unten und beachten Sie das Muster 1-2-4-8 (Verschiebung) 1-2-4-8 (Verschiebung) ...
Um die ursprüngliche Frage zu beantworten, stimme ich @ Sahuagins Vorschlag zu, hexadezimale Literale zu verwenden. Wenn Sie häufig genug mit Binärzahlen arbeiten, damit dies ein Problem darstellt, lohnt es sich, sich mit Hexadezimal zu beschäftigen.
Wenn Sie Binärzahlen im Quellcode sehen müssen, schlage ich vor, Kommentare mit Binärliteralen wie oben hinzuzufügen.
Wenn Sie sie häufig verwenden, können Sie sie zur Wiederverwendung in eine statische Klasse einschließen.
Wenn Sie jedoch eine Semantik haben, die mit den Bits verknüpft ist (zur Kompilierungszeit bekannt), würde ich empfehlen, stattdessen eine Aufzählung zu verwenden:
enumFlags{First=0,Second=1,Third=2,SecondAndThird=3}// later ...Debug.Assert((Flags.Second|Flags.Third)==Flags.SecondAndThird);
Wenn Sie sich den Implementierungsstatus der Sprachfunktionen der .NET Compiler-Plattform ("Roslyn") ansehen, können Sie deutlich erkennen, dass dies in C # 6.0 eine geplante Funktion ist. In der nächsten Version können wir dies also auf die übliche Weise tun.
string sTable="static class BinaryTable\r\n{";string stemp ="";for(int i =0; i <256; i++){
stemp =System.Convert.ToString(i,2);while(stemp.Length<8) stemp ="0"+ stemp;
sTable +="\tconst char nb"+ stemp +"="+ i.ToString()+";\r\n";}
sTable +="}";Clipboard.Clear();Clipboard.SetText( sTable);MessageBox.Show(sTable);
Wenn ich dies für 8-Bit-Binärdateien verwende, erstelle ich damit eine statische Klasse und füge sie in die Zwischenablage ein. Dann wird sie in das Projekt eingefügt und dem Abschnitt "Verwenden" hinzugefügt, sodass alles mit nb001010 aus einer Tabelle entfernt wird am wenigsten statisch, aber immer noch ... Ich verwende C # für viele PIC-Grafikcodierungen und verwende 0b101010 häufig in Hi-Tech C.
Die Funktion für binäre Literale wurde in C # 6.0 und Visual Studio 2015 nicht implementiert. Am 30. März 2016 kündigte Microsoft die neue Version von Visual Studio '15' Preview an, mit der wir binäre Literale verwenden können.
Wir können ein oder mehrere Unterstriche (_) für Zifferntrennzeichen verwenden. Das Code-Snippet würde also ungefähr so aussehen:
int x =0b10___10_0__________________00;//binary value of 80intSeventyFive=0B100_________1011;//binary value of 75WriteLine($" {x} \n {SeventyFive}");
und wir können entweder 0b oder 0B verwenden, wie im obigen Codeausschnitt gezeigt.
Wenn Sie kein Zifferntrennzeichen verwenden möchten, können Sie es ohne Zifferntrennzeichen wie im folgenden Codeausschnitt verwenden
int x =0b1010000;//binary value of 80intSeventyFive=0B1001011;//binary value of 75WriteLine($" {x} \n {SeventyFive}");
BitConverter wird etwas knifflig, weil es maschinenendisch ist. und auf Ihrem Standard-Intel bedeutet das Little-Endian. Die meisten Menschen haben Schwierigkeiten, Little-Endian-Literale zu lesen ...
Marc Gravell
1
Autsch, jetzt erinnere ich mich, warum ich den BitConverter immer kannte, aber nie benutzte ...
Michael Stum
4
BitConverter hat das Feld BitConverter.IsLittleEndian, mit dem Sie testen (und einen Puffer umkehren) können, wenn der Host-Computer nicht Little Endian ist.
Foxy
1
Obwohl die String-Parsing-Lösung die beliebteste ist, gefällt sie mir nicht, da das Parsen von Strings in manchen Situationen ein großer Leistungseinbruch sein kann.
Wenn eine Art Bitfeld oder Binärmaske benötigt wird, schreibe ich sie lieber so
Grundsätzlich denke ich, die Antwort ist NEIN, es gibt keinen einfachen Weg. Verwenden Sie Dezimal- oder Hexadezimalkonstanten - sie sind einfach und klar. @ RoyTinkers Antwort ist auch gut - benutze einen Kommentar.
int someHexFlag =0x010;// 000000010000int someDecFlag =8;// 000000001000
Die anderen Antworten hier bieten einige nützliche Arbeitsrunden, aber ich denke, sie sind nicht besser als die einfache Antwort. C # -Sprachendesigner hielten ein Präfix '0b' wahrscheinlich für unnötig. HEX lässt sich leicht in Binärdateien konvertieren, und die meisten Programmierer müssen die DEC-Äquivalente von 0-8 sowieso kennen.
Wenn Sie Werte im Debugger untersuchen, werden sie mit HEX oder DEC angezeigt.
if (a == MaskForModemIOEnabled)
alsif (a == 0b100101)
Antworten:
C # 7.0 unterstützt binäre Literale (und optionale Zifferntrennzeichen über Unterstriche).
Ein Beispiel:
Weitere Informationen finden Sie auch auf der Roslyn GitHub-Seite .
quelle
Int16 = 0b0010_0110_0000_0011
als{ 0b0000_0011, 0b0010_0110 }
- verwirrend gespeichert werden .0xDEADBEEF
wird gespeichert als0xEF 0xBE 0xAD 0xDE
Aktualisieren
C # 7.0 hat jetzt binäre Literale, was großartig ist.
Ursprünglicher Beitrag
Da sich das Thema anscheinend darauf konzentriert hat, bitbasierte Flag-Werte in Aufzählungen zu deklarieren, hielt ich es für sinnvoll, auf einen praktischen Trick für diese Art von Dingen hinzuweisen. Mit dem Linksverschiebungsoperator (
<<
) können Sie ein bisschen an eine bestimmte Binärposition drücken. Kombinieren Sie dies mit der Möglichkeit, Enum-Werte in Bezug auf andere Werte in derselben Klasse zu deklarieren, und Sie haben eine sehr einfach zu lesende deklarative Syntax für Bit-Flag-Enums.quelle
Ich fürchte, nur Ganzzahl und Hex direkt (ECMA 334v4):
Zum Parsen können Sie Folgendes verwenden:
quelle
Neben der Antwort von @ StriplingWarrior zu Bit-Flags in Aufzählungen gibt es eine einfache Konvention, die Sie hexadezimal verwenden können, um durch die Bitverschiebungen nach oben zu zählen. Verwenden Sie die Sequenz 1-2-4-8, verschieben Sie eine Spalte nach links und wiederholen Sie den Vorgang.
Scannen Sie ab der rechten Spalte nach unten und beachten Sie das Muster 1-2-4-8 (Verschiebung) 1-2-4-8 (Verschiebung) ...
Um die ursprüngliche Frage zu beantworten, stimme ich @ Sahuagins Vorschlag zu, hexadezimale Literale zu verwenden. Wenn Sie häufig genug mit Binärzahlen arbeiten, damit dies ein Problem darstellt, lohnt es sich, sich mit Hexadezimal zu beschäftigen.
Wenn Sie Binärzahlen im Quellcode sehen müssen, schlage ich vor, Kommentare mit Binärliteralen wie oben hinzuzufügen.
quelle
Sie können jederzeit Quasi-Literale erstellen, Konstanten, die den gewünschten Wert enthalten:
Wenn Sie sie häufig verwenden, können Sie sie zur Wiederverwendung in eine statische Klasse einschließen.
Wenn Sie jedoch eine Semantik haben, die mit den Bits verknüpft ist (zur Kompilierungszeit bekannt), würde ich empfehlen, stattdessen eine Aufzählung zu verwenden:
quelle
Wenn Sie sich den Implementierungsstatus der Sprachfunktionen der .NET Compiler-Plattform ("Roslyn") ansehen, können Sie deutlich erkennen, dass dies in C # 6.0 eine geplante Funktion ist. In der nächsten Version können wir dies also auf die übliche Weise tun.
quelle
Wenn ich dies für 8-Bit-Binärdateien verwende, erstelle ich damit eine statische Klasse und füge sie in die Zwischenablage ein. Dann wird sie in das Projekt eingefügt und dem Abschnitt "Verwenden" hinzugefügt, sodass alles mit nb001010 aus einer Tabelle entfernt wird am wenigsten statisch, aber immer noch ... Ich verwende C # für viele PIC-Grafikcodierungen und verwende 0b101010 häufig in Hi-Tech C.
- Beispiel aus Code outpt--
:-) NEAL
quelle
Die Funktion für binäre Literale wurde in C # 6.0 und Visual Studio 2015 nicht implementiert. Am 30. März 2016 kündigte Microsoft die neue Version von Visual Studio '15' Preview an, mit der wir binäre Literale verwenden können.
Wir können ein oder mehrere Unterstriche (_) für Zifferntrennzeichen verwenden. Das Code-Snippet würde also ungefähr so aussehen:
und wir können entweder 0b oder 0B verwenden, wie im obigen Codeausschnitt gezeigt.
Wenn Sie kein Zifferntrennzeichen verwenden möchten, können Sie es ohne Zifferntrennzeichen wie im folgenden Codeausschnitt verwenden
quelle
Ein BitConverter ist zwar nicht mit einem Literal möglich, kann aber auch eine Lösung sein?
quelle
BitConverter.IsLittleEndian
, mit dem Sie testen (und einen Puffer umkehren) können, wenn der Host-Computer nicht Little Endian ist.Obwohl die String-Parsing-Lösung die beliebteste ist, gefällt sie mir nicht, da das Parsen von Strings in manchen Situationen ein großer Leistungseinbruch sein kann.
Wenn eine Art Bitfeld oder Binärmaske benötigt wird, schreibe ich sie lieber so
Und später
Oder
Wo sich die BitField-Klasse befindet
quelle
Sie können
0b000001
seit Visual Studio 2017 (C # 7.0) verwendenquelle
Grundsätzlich denke ich, die Antwort ist NEIN, es gibt keinen einfachen Weg. Verwenden Sie Dezimal- oder Hexadezimalkonstanten - sie sind einfach und klar. @ RoyTinkers Antwort ist auch gut - benutze einen Kommentar.
Die anderen Antworten hier bieten einige nützliche Arbeitsrunden, aber ich denke, sie sind nicht besser als die einfache Antwort. C # -Sprachendesigner hielten ein Präfix '0b' wahrscheinlich für unnötig. HEX lässt sich leicht in Binärdateien konvertieren, und die meisten Programmierer müssen die DEC-Äquivalente von 0-8 sowieso kennen.
Wenn Sie Werte im Debugger untersuchen, werden sie mit HEX oder DEC angezeigt.
quelle