c# - reservada - significado de double en lenguaje c
C#literales binarios (12)
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 sintaxis 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
}
¿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?
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.
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 programadores 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.
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 .
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}");
Puede usar 0b000001
desde Visual Studio 2017 (C # 7.0)
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);
Si bien no es posible utilizar un Literal, tal vez un BitConverter también puede ser una solución?
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.
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 compilació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);
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 codificación 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