Existe-t-il un moyen d'écrire des littéraux binaires en C #, comme préfixer hexadécimal avec 0x? 0b ne fonctionne pas.
Sinon, quelle est la manière la plus simple de le faire? Une sorte de conversion de chaîne?
Existe-t-il un moyen d'écrire des littéraux binaires en C #, comme préfixer hexadécimal avec 0x? 0b ne fonctionne pas.
Sinon, quelle est la manière la plus simple de le faire? Une sorte de conversion de chaîne?
Réponses:
C # 7.0 prend en charge les littéraux binaires (et les séparateurs de chiffres facultatifs via des caractères de soulignement).
Un exemple:
int myValue = 0b0010_0110_0000_0011;
Vous pouvez également trouver plus d'informations sur la page Roslyn GitHub .
Int16 = 0b0010_0110_0000_0011
seront stockés comme { 0b0000_0011, 0b0010_0110 }
- déroutant.
0xDEADBEEF
sera stocké comme0xEF 0xBE 0xAD 0xDE
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
}
Puisque le sujet semble s'être tourné vers la déclaration de valeurs d'indicateur basées sur les bits dans les énumérations, j'ai pensé qu'il serait intéressant de souligner une astuce pratique pour ce genre de chose. L'opérateur de décalage à gauche ( <<
) vous permettra de pousser un peu vers une position binaire spécifique. Combinez cela avec la possibilité de déclarer des valeurs d'énumération en termes d'autres valeurs dans la même classe, et vous avez une syntaxe déclarative très facile à lire pour les énumérations 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
}
Seuls les nombres entiers et hexadécimaux directement, j'ai peur (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écimale et hexadécimale.
Pour analyser, vous pouvez utiliser:
int i = Convert.ToInt32("01101101", 2);
En plus de la réponse de @ StriplingWarrior sur les indicateurs de bits dans les énumérations, il existe une convention simple que vous pouvez utiliser en hexadécimal pour compter vers le haut à travers les décalages de bits. Utilisez la séquence 1-2-4-8, déplacez une colonne vers la gauche et répétez.
[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
}
Balayez vers le bas en commençant par la colonne de droite et notez 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 assez souvent avec des nombres binaires pour que cela soit un problème, 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 je l'ai fait ci-dessus.
Vous pouvez toujours créer des quasi-littéraux, des constantes qui contiennent 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 d'utiliser un Enum à la place:
enum Flags
{
First = 0,
Second = 1,
Third = 2,
SecondAndThird = 3
}
// later ...
Debug.Assert((Flags.Second | Flags.Third) == Flags.SecondAndThird);
Si vous regardez l' état d'implémentation des fonctionnalités de langage de la plate-forme du compilateur .NET ("Roslyn"), vous pouvez clairement voir que dans C # 6.0, il s'agit d'une fonctionnalité prévue, donc dans la prochaine version, nous pouvons le faire de la manière habituelle.
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 ceci, pour le binaire 8 bits, je l'utilise pour créer une classe statique et la place dans le presse-papiers. Ensuite, elle est collée dans le projet et ajoutée à la section Utilisation, donc tout ce qui contient nb001010 est retiré d'une table moins statique, mais quand même ... j'utilise C # pour beaucoup de codage graphique PIC et j'utilise beaucoup 0b101010 en Hi-Tech C
--échantillon à partir de la sortie de code--
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
La fonctionnalité de littéral 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 avec laquelle nous pouvons utiliser des littéraux binaires.
Nous pouvons utiliser un ou plusieurs caractères de soulignement (_) pour les séparateurs de chiffres. donc l'extrait de code ressemblerait à 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 de séparateur de chiffres, vous pouvez l'utiliser sans séparateur de chiffres comme ci-dessous l'extrait de code
int x = 0b1010000; //binary value of 80
int SeventyFive = 0B1001011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
Bien qu'il ne soit pas possible d'utiliser un littéral, peut-être qu'un BitConverter peut également être une solution?
BitConverter.IsLittleEndian
, que vous pouvez utiliser pour tester (et inverser un tampon) si la machine hôte n'est pas peu endian.
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 grand succès en termes de performances dans certaines situations.
Quand il faut une sorte de champ de bits ou de masque binaire, je préfère l'écrire comme
bitMask long = 1011001;
Et ensuite
int bit5 = BitField.GetBit (bitMask, 5);
Ou
booléen flag5 = BitField.GetFlag (bitMask, 5); `
Où se trouve 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;
}
}
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 @RoyTinkers est également bonne - utilisez un commentaire.
int someHexFlag = 0x010; // 000000010000
int someDecFlag = 8; // 000000001000
Les autres réponses ici présentent plusieurs séries de 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é un préfixe «0b» inutile. 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.
if (a == MaskForModemIOEnabled)
plutôt queif (a == 0b100101)