web-dev-qa-db-fra.com

Littéraux binaires C #

Y a-t-il un moyen d'écrire des littéraux binaires en C #, comme préfixer hexadécimal avec 0x? 0b ne fonctionne pas.

Si non, quel est un moyen facile de le faire? Une sorte de conversion de chaîne?

170
toxvaerd

C # 7. supporte littéraux binaires (et séparateurs de chiffres optionnels via des caractères de soulignement).

Un exemple:

int myValue = 0b0010_0110_0000_0011;

Vous pouvez également trouver plus d'informations sur le page Roslyn GitHub .

123
BTownTKD

Mise à jour

C # 7.0 a maintenant des littéraux binaires, ce qui est génial.

[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
}

Poste originale

Étant donné que le sujet semble s’être tourné vers la déclaration des valeurs de drapeau basées sur des bits dans les énumérations, j’ai pensé qu’il serait utile de signaler une astuce pratique pour ce genre de chose. L’opérateur de gauche (<<) vous permettra de pousser un bit vers une position binaire spécifique. Combinez cela avec la possibilité de déclarer des valeurs enum en termes d'autres valeurs de la même classe, et vous obtenez une syntaxe déclarative très facile à lire pour les enum d'indicateurs de bits.

[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
StriplingWarrior

Je crains seulement les nombres entiers et les hexagones directement (ECMA 334v4):

9.4.4.2 Littéraux entiers Les littéraux entiers sont utilisés pour écrire des valeurs de types int, uint, long et ulong. Les littéraux entiers ont deux formes possibles: décimal et hexadécimal.

Pour analyser, vous pouvez utiliser:

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

En ajoutant à la réponse de @ StriplingWarrior à propos des indicateurs de bits dans les énumérations, il existe une convention simple que vous pouvez utiliser en hexadécimal pour compter de manière ascendante à travers les décalages de bits. Utilisez la séquence 1-2-4-8, déplacez une colonne à gauche et répétez l'opération.

[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
}

Parcourez la colonne de droite en commençant par la colonne de droite et remarquez le motif 1-2-4-8 (décalage) 1-2-4-8 (décalage) ...


Pour répondre à la question initiale, j'appuie la suggestion de @ Sahuagin d'utiliser des littéraux hexadécimaux. Si vous travaillez avec des nombres binaires assez souvent pour que cela soit une préoccupation, cela vaut la peine de maîtriser l'hexadécimal.

Si vous avez besoin de voir des nombres binaires dans le code source, je suggère d’ajouter des commentaires avec des littéraux binaires comme ci-dessus.

25
Roy Tinker

Vous pouvez toujours créer des quasi-littéraux, des constantes contenant la valeur que vous recherchez:

const int b001 = 1;
const int b010 = 2;
const int b011 = 3;
// etc ...
Debug.Assert((b001 | b010) == b011);

Si vous les utilisez souvent, vous pouvez les envelopper dans une classe statique pour les réutiliser.

Cependant, légèrement hors sujet, si vous avez une sémantique associée aux bits (connue au moment de la compilation), je suggérerais plutôt d'utiliser un énum à la place:

enum Flags
{ 
    First = 0,
    Second = 1,
    Third = 2,
    SecondAndThird = 3
}
// later ...
Debug.Assert((Flags.Second | Flags.Third) == Flags.SecondAndThird);
22
Markus Johnsson

Si vous examinez le état d'implémentation des fonctionnalités du langage de la plate-forme du compilateur .NET ("Roslyn"), vous pouvez voir clairement que, dans C # 6.0, il s'agit d'une fonctionnalité planifiée. Nous pouvons donc le faire dans la prochaine version. de la manière habituelle.

Binary literal status

18
totymedli

La fonctionnalité littérale binaire n'a pas été implémentée dans C # 6.0 et Visual Studio 2015. Mais le 30 mars 2016, Microsoft a annoncé la nouvelle version de Visual Studio '15' Preview permettant d'utiliser des littéraux binaires.

Nous pouvons utiliser un ou plusieurs caractères de soulignement (_) pour les séparateurs de chiffres. si l'extrait de code ressemble à quelque chose comme:

int x           = 0b10___10_0__________________00; //binary value of 80
int SeventyFive = 0B100_________1011; //binary value of 75

WriteLine($" {x} \n {SeventyFive}");

et nous pouvons utiliser 0b et 0B comme indiqué dans l'extrait de code ci-dessus.

si vous ne voulez pas utiliser le séparateur de chiffres, vous pouvez l'utiliser sans séparateur de chiffres, comme ci-dessous le code snippet

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

WriteLine($" {x} \n {SeventyFive}");
3
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);

En utilisant cela, pour les fichiers binaires 8 bits, je l’utilise pour créer une classe statique qu’elle place dans le presse-papiers. Elle est ensuite collée dans le projet et ajoutée à la section Using, de sorte que tout élément associé à nb001010 est extrait d’un tableau. moins statique, mais quand même ... J'utilise C # pour beaucoup de codage graphique PIC et utilise beaucoup 0b101010 dans Hi-Tech C

--exemple du 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

Bien qu’il ne soit pas possible d’utiliser un littéral, un BitConverter peut également être une solution?

2
Michael Stum

Bien que la solution d'analyse de chaîne soit la plus populaire, je ne l'aime pas, car l'analyse de chaîne peut être un problème de performances dans certaines situations.

Quand on a besoin d’une sorte de masque de champ de bits ou de binaire, je l’écris plutôt comme

masque de bits long = 1011001;

Et ensuite

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

Ou

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

Où est la classe BitField

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
Dmitry Tashkinov

Vous pouvez utiliser 0b000001 depuis Visual Studio 2017 (C # 7.0)

1
Xiaoyuvax

Fondamentalement, je pense que la réponse est NON, il n'y a pas de moyen facile. Utilisez des constantes décimales ou hexadécimales - elles sont simples et claires. La réponse de @RoyTinkers est également bonne - utilisez un commentaire.

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

Les autres réponses ici présentent plusieurs travaux utiles, mais je pense qu’elles ne sont pas meilleures que la réponse simple. Les concepteurs de langage C # ont probablement considéré qu'un préfixe '0b' n'était pas nécessaire. HEX est facile à convertir en binaire, et la plupart des programmeurs devront de toute façon connaître les équivalents DEC de 0 à 8.

De plus, lors de l'examen des valeurs dans le débogueur, elles seront affichées avec HEX ou DEC.

0
RaoulRubin