C # literales binarios

¿Hay alguna manera de escribir literales binarios en C #, como prefijar hexadecimal con 0x? 0b no funciona.

Si no, ¿cuál es una manera fácil de hacerlo? Algún tipo de conversión de cadena?

C # 7.0 admite literales binarios (y separadores de dígitos opcionales mediante caracteres de subrayado).

Un ejemplo:

 int myValue = 0b0010_0110_0000_0011; 

También puede encontrar más información en la página de Roslyn GitHub .

Actualizar

C # 7.0 ahora tiene literales binarios, lo cual es asombroso.

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

Publicación original

Dado que el tema parece haber pasado a declarar valores de indicadores basados ​​en bits en enumeraciones, pensé que sería útil señalar un truco útil para este tipo de cosas. El operador de desplazamiento a la izquierda ( << ) le permitirá presionar un bit en una posición binaria específica. Combine eso con la capacidad de declarar valores de enum en términos de otros valores en la misma clase, y tiene una syntax declarativa muy fácil de leer para enum de indicadores 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 } 

Sólo enteros y hexadecimal directamente, me temo (ECMA 334v4):

9.4.4.2 Literales enteros Los literales enteros se utilizan para escribir valores de los tipos int, uint, long y ulong. Los literales enteros tienen dos formas posibles: decimal y hexadecimal.

Para analizar, puedes usar:

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

Agregando a la respuesta de @ StriplingWarrior sobre bit flags en enums, hay una convención fácil que puede usar en hexadecimal para contar hacia arriba a través de los cambios de bit. Usa la secuencia 1-2-4-8, mueve una columna hacia la izquierda y repite.

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

Escanee hacia abajo comenzando por la columna de la derecha y observe el patrón 1-2-4-8 (cambio) 1-2-4-8 (desplazamiento) …


Para responder a la pregunta original, secundo la sugerencia de @ Sahuagin de usar literales hexadecimales. Si trabajas con números binarios con la suficiente frecuencia para que esto sea una preocupación, vale la pena tomar el control hexadecimal.

Si necesita ver números binarios en el código fuente, sugiero que agregue comentarios con literales binarios como los que mencioné anteriormente.

Siempre puede crear cuasi-literales, constantes que contienen el valor que está buscando:

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

Si los usa a menudo, puede envolverlos en una clase estática para su reutilización.

Sin embargo, levemente fuera de tema, si tiene alguna semántica asociada con los bits (conocida en tiempo de comstackción), sugeriría usar un Enum:

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

Si observa el estado de implementación de la característica de idioma de .NET Compiler Platform (“Roslyn”), puede ver claramente que en C # 6.0 esta es una función planificada, por lo que en la próxima versión podemos hacerlo de la forma habitual.

Estado literal binario

 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 esto, para el binario de 8 bits, uso esto para hacer una clase estática y la coloca en el portapapeles. Luego se pega en el proyecto y se agrega a la sección de Uso, de modo que cualquier elemento con nb001010 se saca de la tabla, en menos estático, pero aún así ... Utilizo C # para una gran cantidad de encoding de gráficos PIC y uso mucho el 0b101010 en Hi-Tech C

--muestra de código 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

Si bien no es posible utilizar un Literal, tal vez un BitConverter también puede ser una solución?

La característica literal binaria no se implementó en C # 6.0 y Visual Studio 2015, pero el 30 de marzo de 2016 Microsoft anunció la nueva versión de Visual Studio ’15’ Preview con la que podemos usar literales binarios.

Podemos usar uno o más caracteres de Subrayado (_) para separadores de dígitos. por lo que el fragmento de código sería algo así como:

 int x = 0b10___10_0__________________00; //binary value of 80 int SeventyFive = 0B100_________1011; //binary value of 75 WriteLine($" {x} \n {SeventyFive}"); 

y podemos usar cualquiera de 0b y 0B como se muestra en el fragmento de código anterior.

si no desea utilizar el separador de dígitos, puede usarlo sin un separador de dígitos, como el siguiente fragmento de código

 int x = 0b1010000; //binary value of 80 int SeventyFive = 0B1001011; //binary value of 75 WriteLine($" {x} \n {SeventyFive}"); 

Aunque la solución de análisis de cadenas es la más popular, no me gusta, porque el análisis de cadenas puede ser un gran golpe de rendimiento en algunas situaciones.

Cuando se necesita una especie de máscara bitfield o binaria, prefiero escribirla como

long bitMask = 1011001;

Y después

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

O

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

Donde la clase BitField es

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

Básicamente, creo que la respuesta es NO, no hay una manera fácil. Use constantes decimales o hexadecimales, son simples y claras. La respuesta de @RoyTinkers también es buena, use un comentario.

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

Las otras respuestas aquí presentan varios trabajos útiles, una ronda, pero creo que no son mejores que la respuesta simple. Los diseñadores de lenguaje C # probablemente consideraron innecesario el prefijo ‘0b’. HEX es fácil de convertir a binario, y la mayoría de los progtwigdores van a tener que saber los equivalentes DEC de 0-8 de todos modos.

Además, al examinar valores en el depurador, se mostrarán con HEX o DEC.

Puede usar 0b000001 desde Visual Studio 2017 (C # 7.0)