Utilisez des constantes et donnez-leur des noms propres, le fait que vous deviez les écrire en décimal ne devrait pas avoir d'importance. Personnellement, je voudrais lire if (a == MaskForModemIOEnabled)plutôt queif (a == 0b100101)
Lasse V. Karlsen
2
Une autre note: Si vous avez trouvé ce message parce que vous voulez un champ de bits, veuillez considérer l'attribut flags
toxvaerd
17
Ces deux très bons conseils, sauf lors de la définition desdits champs de bits, où ces définitions de constantes nommées peuvent être plus faciles à lire et à écrire avec un littéral binaire. [Flags] enum Quantity {None = 0, One = 1, Some = 0b10, Most = 0b100, All = 0b111}
Il est utile de se rappeler que les littéraux binaires de C # sont big-endian, mais sur x86, les entiers sont little-endian, donc Int16 = 0b0010_0110_0000_0011seront stockés comme { 0b0000_0011, 0b0010_0110 }- déroutant.
Dai
1
@Dai ce n'est pas différent des littéraux hexadécimaux. En d'autres termes, toutes les constantes sont big endian, mais stockées little endian sur Intel / AMD et la plupart des ARM. 0xDEADBEEFsera stocké comme0xEF 0xBE 0xAD 0xDE
Cole Johnson le
173
Mise à jour
C # 7.0 a maintenant des littéraux binaires, ce qui est génial.
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.
@ColeJohnson: De nombreux développeurs préfèrent cela. Je ne suis pas aussi doué pour convertir l'hexagone dans ma tête que certains développeurs, et parfois il est préférable de prendre en compte le plus petit dénominateur commun.
StriplingWarrior
2
Je pense que c'est le moyen le plus efficace puisque les énumérations sont construites sous forme de constantes. Avec l'attribut facultatif [Flags], ils peuvent être utilisés dans des opérations au niveau du bit (non directement liées à la question, mais particulièrement utiles pour décrire des littéraux binaires). Une autre possibilité intéressante est de forcer le type enum comme type intégré (dans cet exemple, ajoutez ': byte' après 'Days'); voir les types intégrés
caligari
C'est en fait très facile à lire, bien que déclarer un drapeau 0 sur un Enum soit une assez mauvaise pratique
MikeT
6
@MikeT: Pouvez-vous élaborer (ou fournir un lien qui élabore) sur cette dernière pensée? Je déclare souvent des énumérations qui commencent par "1" parce que je veux pouvoir détecter et échouer rapidement lorsqu'une valeur n'a tout simplement jamais été initialisée. Mais il y a des situations où une valeur par défaut a du sens, et je pense qu'il n'y aurait rien de mal à ajouter un nom pour cette valeur.
StriplingWarrior
3
@MikeT From ca1008 : "Si une énumération qui a le FlagsAttribute appliqué définit un membre de valeur zéro, son nom doit être 'None' pour indiquer qu'aucune valeur n'a été définie dans l'énumération." Il est donc parfaitement valable de l'ajouter pour servir de valeur par défaut, s'il s'appelle "Aucun". Dans l'ensemble, cela me semble plus propre si la valeur d'un champ initialisé par défaut a réellement un nom à afficher.
Nyerguds
115
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.
En tant que mise à jour de cette réponse, avec les dernières informations modernes de pointe (juillet 2014); C # 6.0 introduit les littéraux binaires. Voir ma réponse mise à jour wayyyyyy en bas ...
BTownTKD
2
@BTownTKD votre réponse est en fait en haut :) car c'est la réponse acceptée.
RBT
26
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.
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.
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.
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
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 80int 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 80int SeventyFive = 0B1001011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
BitConverter devient un peu délicat car il est machine-endian; et sur votre Intel standard, cela signifie petit-boutiste. La plupart des gens ont de la difficulté à lire les littéraux little-endian ...
Marc Gravell
1
Aïe, maintenant je me souviens pourquoi j'ai toujours été au courant mais je n'ai jamais utilisé le BitConverter ...
Michael Stum
4
BitConverter a le champ BitConverter.IsLittleEndian, que vous pouvez utiliser pour tester (et inverser un tampon) si la machine hôte n'est pas peu endian.
foxy
1
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
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.
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)
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 .
la source
Int16 = 0b0010_0110_0000_0011
seront stockés comme{ 0b0000_0011, 0b0010_0110 }
- déroutant.0xDEADBEEF
sera stocké comme0xEF 0xBE 0xAD 0xDE
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 }
Message original
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 }
la source
Seuls les nombres entiers et hexadécimaux directement, j'ai peur (ECMA 334v4):
Pour analyser, vous pouvez utiliser:
int i = Convert.ToInt32("01101101", 2);
la source
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.
la source
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);
la source
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.
la source
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 source
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}");
la source
Bien qu'il ne soit pas possible d'utiliser un littéral, peut-être qu'un BitConverter peut également être une solution?
la source
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
Et ensuite
Ou
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; } }
la source
Vous pouvez utiliser
0b000001
depuis Visual Studio 2017 (C # 7.0)la source
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.
la source