Gibt es eine Möglichkeit, binäre Literale in C # zu schreiben, z. B. hexadezimal 0x voranzustellen? 0b funktioniert nicht.
Wenn nicht, wie geht das einfach? Eine Art String-Konvertierung?
Gibt es eine Möglichkeit, binäre Literale in C # zu schreiben, z. B. hexadezimal 0x voranzustellen? 0b funktioniert nicht.
Wenn nicht, wie geht das einfach? Eine Art String-Konvertierung?
Antworten:
C # 7.0 unterstützt binäre Literale (und optionale Zifferntrennzeichen über Unterstriche).
Ein Beispiel:
int myValue = 0b0010_0110_0000_0011;
Weitere Informationen finden Sie auch auf der Roslyn GitHub-Seite .
Int16 = 0b0010_0110_0000_0011
als { 0b0000_0011, 0b0010_0110 }
- verwirrend gespeichert werden .
0xDEADBEEF
wird gespeichert als0xEF 0xBE 0xAD 0xDE
C # 7.0 hat jetzt binäre Literale, was großartig ist.
[Flags]
enum Days
{
None = 0,
Sunday = 0b0000001,
Monday = 0b0000010, // 2
Tuesday = 0b0000100, // 4
Wednesday = 0b0001000, // 8
Thursday = 0b0010000, // 16
Friday = 0b0100000, // etc.
Saturday = 0b1000000,
Weekend = Saturday | Sunday,
Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday
}
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.
[Flags]
enum Days
{
None = 0,
Sunday = 1,
Monday = 1 << 1, // 2
Tuesday = 1 << 2, // 4
Wednesday = 1 << 3, // 8
Thursday = 1 << 4, // 16
Friday = 1 << 5, // etc.
Saturday = 1 << 6,
Weekend = Saturday | Sunday,
Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday
}
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.
Zum Parsen können Sie Folgendes verwenden:
int i = Convert.ToInt32("01101101", 2);
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.
[Flags]
enum Scenery
{
Trees = 0x001, // 000000000001
Grass = 0x002, // 000000000010
Flowers = 0x004, // 000000000100
Cactus = 0x008, // 000000001000
Birds = 0x010, // 000000010000
Bushes = 0x020, // 000000100000
Shrubs = 0x040, // 000001000000
Trails = 0x080, // 000010000000
Ferns = 0x100, // 000100000000
Rocks = 0x200, // 001000000000
Animals = 0x400, // 010000000000
Moss = 0x800, // 100000000000
}
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.
Sie können jederzeit Quasi-Literale erstellen, Konstanten, die den gewünschten Wert enthalten:
const int b001 = 1;
const int b010 = 2;
const int b011 = 3;
// etc ...
Debug.Assert((b001 | b010) == b011);
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:
enum Flags
{
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.
- Beispiel aus Code outpt--
static class BinaryTable
{ const char nb00000000=0;
const char nb00000001=1;
const char nb00000010=2;
const char nb00000011=3;
const char nb00000100=4;
//etc, etc, etc, etc, etc, etc, etc,
}
:-) NEAL
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 80
int SeventyFive = 0B100_________1011; //binary value of 75
WriteLine($" {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 80
int SeventyFive = 0B1001011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
Ein BitConverter ist zwar nicht mit einem Literal möglich, kann aber auch eine Lösung sein?
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
lange Bitmaske = 1011001;
Und später
int bit5 = BitField.GetBit (bitMask, 5);
Oder
bool flag5 = BitField.GetFlag (bitMask, 5); `
Wo sich die BitField-Klasse befindet
public static class BitField
{
public static int GetBit(int bitField, int index)
{
return (bitField / (int)Math.Pow(10, index)) % 10;
}
public static bool GetFlag(int bitField, int index)
{
return GetBit(bitField, index) == 1;
}
}
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; // 000000010000
int 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)