¿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?
¿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?
Respuestas:
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 .
Int16 = 0b0010_0110_0000_0011
lo que se almacenarán como { 0b0000_0011, 0b0010_0110 }
confusos.
0xDEADBEEF
será almacenado como0xEF 0xBE 0xAD 0xDE
C # 7.0 ahora tiene literales binarios, lo cual es increíble.
[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
}
Dado que el tema parece haberse convertido en declarar valores de bandera basados en bits en enumeraciones, pensé que valdría la pena señalar un truco útil para este tipo de cosas. El operador de desplazamiento a la izquierda ( <<
) le permitirá empujar un poco a una posición binaria específica. Combine eso con la capacidad de declarar valores de enumeración en términos de otros valores en la misma clase, y tendrá una sintaxis declarativa muy fácil de leer para enumeraciones de marcas 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
}
Solo entero 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, puede usar:
int i = Convert.ToInt32("01101101", 2);
Agregando a la respuesta de @ StriplingWarrior sobre las banderas de bits en las enumeraciones, hay una convención fácil que puede usar en hexadecimal para contar hacia arriba a través de los cambios de bits. Use la secuencia 1-2-4-8, mueva una columna a la izquierda y repita.
[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 con la columna derecha y observe el patrón 1-2-4-8 (turno) 1-2-4-8 (turno) ...
Para responder a la pregunta original, secundo la sugerencia de @ Sahuagin de usar literales hexadecimales. Si está trabajando con números binarios con la suficiente frecuencia como para que esto sea una preocupación, vale la pena aprender el hexadecimal.
Si necesita ver números binarios en el código fuente, sugiero agregar comentarios con literales binarios como los que he mencionado anteriormente.
Siempre puede crear cuasi literales, constantes que contengan el valor que busca:
const int b001 = 1;
const int b010 = 2;
const int b011 = 3;
// etc ...
Debug.Assert((b001 | b010) == b011);
Si los usa con frecuencia, puede envolverlos en una clase estática para su reutilización.
Sin embargo, un poco fuera de tema, si tiene alguna semántica asociada con los bits (conocida en tiempo de compilación) sugeriría usar una Enum en su lugar:
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 función de lenguaje 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 manera habitual.
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 binario de 8 bits, lo uso 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 Uso, por lo que cualquier cosa con nb001010 se saca de una tabla, en menos estático, pero aún así ... uso C # para una gran cantidad de codificación de gráficos PIC y uso mucho 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
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 de los caracteres de subrayado (_) para los separadores de dígitos. para que el fragmento de código se vea así:
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 0b y 0B como se muestra en el fragmento de código anterior.
si no desea usar un separador de dígitos, puede usarlo sin un separador de dígitos como el fragmento de código a continuación
int x = 0b1010000; //binary value of 80
int SeventyFive = 0B1001011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
Si bien no es posible usar un Literal, ¿tal vez un BitConverter también puede ser una solución?
BitConverter.IsLittleEndian
, que puede usar para probar (y revertir un búfer) si la máquina host no es poco endian.
Aunque la solución de análisis de cadenas es la más popular, no me gusta, porque analizar cadenas puede ser un gran éxito en algunas situaciones.
Cuando se necesita un tipo de campo de bits o máscara binaria, prefiero escribirlo como
bitMask largo = 1011001;
Y después
int bit5 = BitField.GetBit (bitMask, 5);
O
bool flag5 = BitField.GetFlag (bitMask, 5); `
Donde está la clase 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;
}
}
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 varias rondas de trabajo útiles, pero creo que no son mejores que la respuesta simple. Los diseñadores de lenguaje C # probablemente consideraron innecesario un prefijo '0b'. HEX es fácil de convertir a binario, y la mayoría de los programadores tendrán que conocer los equivalentes DEC de 0-8 de todos modos.
Además, al examinar los valores en el depurador, se mostrarán como HEX o DEC.
if (a == MaskForModemIOEnabled)
lugar deif (a == 0b100101)