C'è un modo per scrivere letterali binari in C #, come il prefisso esadecimale con 0x? 0b non funziona.
In caso contrario, qual è un modo semplice per farlo? Qualche tipo di conversione di stringa?
C'è un modo per scrivere letterali binari in C #, come il prefisso esadecimale con 0x? 0b non funziona.
In caso contrario, qual è un modo semplice per farlo? Qualche tipo di conversione di stringa?
Risposte:
C # 7.0 supporta valori letterali binari (e separatori di cifre opzionali tramite caratteri di sottolineatura).
Un esempio:
int myValue = 0b0010_0110_0000_0011;
Puoi anche trovare maggiori informazioni sulla pagina Roslyn GitHub .
Int16 = 0b0010_0110_0000_0011
verranno memorizzati come { 0b0000_0011, 0b0010_0110 }
- confusi.
0xDEADBEEF
sarà memorizzato come0xEF 0xBE 0xAD 0xDE
C # 7.0 ora ha letterali binari, il che è fantastico.
[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
}
Dato che l'argomento sembra essersi rivolto alla dichiarazione di valori di flag basati su bit negli enum, ho pensato che valesse la pena sottolineare un trucco utile per questo genere di cose. L'operatore di spostamento a sinistra ( <<
) ti permetterà di spingere un po 'verso una posizione binaria specifica. Combinalo con la capacità di dichiarare i valori enum in termini di altri valori nella stessa classe e avrai una sintassi dichiarativa molto facile da leggere per gli enum di flag di bit.
[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
}
Ho solo direttamente numeri interi ed esadecimali, temo (ECMA 334v4):
9.4.4.2 Letterali interi I letterali interi vengono utilizzati per scrivere valori di tipi int, uint, long e ulong. I letterali interi hanno due forme possibili: decimale ed esadecimale.
Per analizzare, puoi usare:
int i = Convert.ToInt32("01101101", 2);
Aggiungendo alla risposta di @ StriplingWarrior sulle flag di bit negli enum, c'è una semplice convenzione che puoi usare in esadecimale per contare verso l'alto attraverso i bit shift. Utilizzare la sequenza 1-2-4-8, spostare una colonna a sinistra e ripetere.
[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
}
Scorri verso il basso a partire dalla colonna di destra e osserva il modello 1-2-4-8 (spostamento) 1-2-4-8 (spostamento) ...
Per rispondere alla domanda originale, secondo il suggerimento di @ Sahuagin di usare letterali esadecimali. Se stai lavorando con numeri binari abbastanza spesso da essere fonte di preoccupazione, vale la pena dedicare del tempo all'esadecimale.
Se hai bisogno di vedere i numeri binari nel codice sorgente, ti suggerisco di aggiungere commenti con valori letterali binari come ho sopra.
Puoi sempre creare quasi-letterali, costanti che contengono il valore che stai cercando:
const int b001 = 1;
const int b010 = 2;
const int b011 = 3;
// etc ...
Debug.Assert((b001 | b010) == b011);
Se li usi spesso, puoi avvolgerli in una classe statica per riutilizzarli.
Tuttavia, leggermente fuori tema, se hai qualche semantica associata ai bit (conosciuta al momento della compilazione), suggerirei invece di usare un Enum:
enum Flags
{
First = 0,
Second = 1,
Third = 2,
SecondAndThird = 3
}
// later ...
Debug.Assert((Flags.Second | Flags.Third) == Flags.SecondAndThird);
Se osservi lo stato di implementazione della funzionalità linguistica della piattaforma di compilatore .NET ("Roslyn") puoi vedere chiaramente che in C # 6.0 questa è una funzionalità pianificata, quindi nella prossima versione possiamo farlo nel solito modo.
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);
Usando questo, per binario a 8 bit, lo uso per creare una classe statica e la inserisce negli Appunti. Quindi viene incollata nel progetto e aggiunta alla sezione Utilizzo, quindi qualsiasi cosa con nb001010 viene estratta da una tabella, in meno statico, ma comunque ... Uso C # per molta codifica grafica PIC e uso 0b101010 molto in Hi-Tech C
--campione dall'output del codice--
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 funzionalità letterale binaria non è stata implementata in C # 6.0 e Visual Studio 2015. Ma il 30 marzo 2016 Microsoft ha annunciato la nuova versione dell'anteprima '15' di Visual Studio con la quale è possibile utilizzare valori letterali binari.
Possiamo usare uno o più caratteri di sottolineatura (_) per i separatori di cifre. quindi lo snippet di codice sarebbe simile a:
int x = 0b10___10_0__________________00; //binary value of 80
int SeventyFive = 0B100_________1011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
e possiamo usare 0b e 0B come mostrato nello snippet di codice sopra riportato.
se non si desidera utilizzare il separatore di cifre, è possibile utilizzarlo senza il separatore di cifre come sotto lo snippet di codice
int x = 0b1010000; //binary value of 80
int SeventyFive = 0B1001011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
Sebbene non sia possibile utilizzare un valore letterale, forse un BitConverter può anche essere una soluzione?
BitConverter.IsLittleEndian
, che è possibile utilizzare per testare (e invertire un buffer) se la macchina host non è poco endian.
Sebbene la soluzione di analisi delle stringhe sia la più popolare, non mi piace, perché l'analisi delle stringhe può essere un grande successo in alcune situazioni.
Quando c'è bisogno di una specie di bitfield o maschera binaria, preferirei scriverlo come
long bitMask = 1011001;
E più tardi
int bit5 = BitField.GetBit (bitMask, 5);
O
bool flag5 = BitField.GetFlag (bitMask, 5); `
Dove si trova 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;
}
}
Fondamentalmente, penso che la risposta sia NO, non esiste un modo semplice. Usa le costanti decimali o esadecimali: sono semplici e chiare. Anche la risposta di @RoyTinkers è buona: usa un commento.
int someHexFlag = 0x010; // 000000010000
int someDecFlag = 8; // 000000001000
Le altre risposte qui presentano alcuni utili round di lavoro, ma penso che non siano migliori della semplice risposta. I progettisti del linguaggio C # probabilmente hanno ritenuto superfluo un prefisso "0b". HEX è facile da convertire in binario e la maggior parte dei programmatori dovrà comunque conoscere gli equivalenti DEC di 0-8.
Inoltre, quando si esaminano i valori nel debugger, verranno visualizzati HEX o DEC.
if (a == MaskForModemIOEnabled)
piuttosto cheif (a == 0b100101)