it-swarm.com.de

C # Binärliterale

Gibt es eine Möglichkeit, Binärliterale in C # zu schreiben, z. B. hexadezimales Voranstellen von 0x? 0b funktioniert nicht.

Wenn nicht, was ist ein einfacher Weg, dies zu tun? Eine Art String-Konvertierung?

170
toxvaerd

C # 7. unterstützt binäre Literale (und optionale Zifferntrennzeichen durch Unterstriche).

Ein Beispiel:

int myValue = 0b0010_0110_0000_0011;

Weitere Informationen finden Sie auch auf der Roslyn GitHub-Seite .

123
BTownTKD

Aktualisieren

C # 7.0 enthält jetzt Binärliterale, was fantastisch 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
}

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 solche Dinge hinzuweisen. Der Linksschieber (<<) ermöglicht es Ihnen, ein Bit an eine bestimmte Binärposition zu verschieben. 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
}
159

Nur Integer und Hex direkt, fürchte ich (ECMA 334v4):

9.4.4.2 Integer-Literale Integer-Literale werden zum Schreiben von Werten der Typen int, uint, long und ulong verwendet. Ganzzahlige Literale haben zwei mögliche Formen: dezimal und hexadezimal.

Zum Parsen können Sie Folgendes verwenden:

int i = Convert.ToInt32("01101101", 2);
115
Marc Gravell

In der Antwort von @ StriplingWarrior zu Bit-Flags in Aufzählungen gibt es eine einfache Konvention, die Sie hexadezimal verwenden können, um 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 beginnend mit 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, empfehle ich @ Sahuagin, hexadezimale Literale zu verwenden. Wenn Sie häufig genug mit Binärzahlen arbeiten, um sich Sorgen zu machen, lohnt es sich, hexadezimal zu arbeiten.

Wenn Sie Binärzahlen im Quellcode sehen müssen, schlage ich vor, Kommentare mit Binärliteralen wie oben hinzuzufügen.

25
Roy Tinker

Sie können immer Quasi-Literale erstellen, Konstanten, die den Wert enthalten, nach dem Sie suchen:

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 in Verbindung steht (zur Kompilierungszeit bekannt), würde ich vorschlagen, 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);
22
Markus Johnsson

Wenn Sie sich Implementierungsstatus der Sprachfunktionen der .NET Compiler-Plattform ("Roslyn") ansehen, sehen Sie deutlich, dass dies in C # 6.0 eine geplante Funktion ist. In der nächsten Version können wir dies also tun auf die übliche Weise.

Binary literal status

18
totymedli

Die Funktion für binäre Literale wurde in C # 6.0 und Visual Studio 2015 nicht implementiert, aber Am 30. März 2016 kündigte Microsoft die neue Version von Visual Studio '15' Preview an, mit der Binärliterale verwendet werden können.

Wir können ein oder mehrere Unterstriche (_) als 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}");

nd wir können entweder 0b oder 0B verwenden, wie im obigen Codeausschnitt gezeigt.

wenn Sie das Zifferntrennzeichen nicht verwenden möchten, können Sie es auch ohne das Zifferntrennzeichen verwenden, wie im folgenden Codeausschnitt dargestellt

int x           = 0b1010000; //binary value of 80
int SeventyFive = 0B1001011; //binary value of 75

WriteLine($" {x} \n {SeventyFive}");
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, verwende ich dies, um eine statische Klasse zu erstellen und sie in die Zwischenablage zu kopieren. Dann wird sie in das Projekt eingefügt und in den Using-Abschnitt eingefügt, sodass alles, was nb001010 enthält, aus einer Tabelle unter entfernt wird Am wenigsten statisch, aber immer noch ... Ich verwende C # für eine Menge PIC-Grafikcodierung und verwende häufig 0b101010 in Hi-Tech C

--sample from 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

3
Neal

Ein Literal ist zwar nicht möglich, aber vielleicht kann ein BitConverter auch eine Lösung sein?

2
Michael Stum

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 es eine Art Bitfeld oder Binärmaske braucht, schreibe ich es lieber so

lange Bitmaske = 1011001;

Und später

int bit5 = BitField.GetBit (bitMask, 5);

Oder

bool flag5 = BitField.GetFlag (bitMask, 5); `

Wo ist die BitField-Klasse?

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;
    }
}
1

Sie können 0b000001 seit Visual Studio 2017 (C # 7.0)

1
Xiaoyuvax

Grundsätzlich denke ich, die Antwort ist NEIN, es gibt keinen einfachen Weg. Verwenden Sie Dezimal- oder Hexadezimal-Konstanten - sie sind einfach und klar. @ RoyTinkers Antwort ist auch gut - verwenden Sie einen Kommentar.

int someHexFlag = 0x010; // 000000010000
int someDecFlag = 8;     // 000000001000

Die anderen Antworten hier präsentieren einige nützliche Arbeitsrunden, aber ich denke, sie sind nicht besser als die einfache Antwort. C # -Sprachdesigner hielten wahrscheinlich ein "0b" -Präfix für unnötig. HEX ist leicht in binär umzuwandeln, und die meisten Programmierer müssen sowieso die DEC-Entsprechungen von 0-8 kennen.

Wenn Sie Werte im Debugger untersuchen, werden diese mit HEX oder DEC angezeigt.

0
RaoulRubin