Existe uma maneira de escrever literais binários em C #, como prefixar hexadecimal com 0x? 0b não funciona.
Caso contrário, qual é a maneira mais fácil de fazer isso? Algum tipo de conversão de string?
Existe uma maneira de escrever literais binários em C #, como prefixar hexadecimal com 0x? 0b não funciona.
Caso contrário, qual é a maneira mais fácil de fazer isso? Algum tipo de conversão de string?
Respostas:
O C # 7.0 suporta literais binários (e separadores de dígitos opcionais por meio de caracteres sublinhados).
Um exemplo:
int myValue = 0b0010_0110_0000_0011;
Você também pode encontrar mais informações na página do Roslyn GitHub .
Int16 = 0b0010_0110_0000_0011
serão armazenados como { 0b0000_0011, 0b0010_0110 }
- confusos.
0xDEADBEEF
será armazenado como0xEF 0xBE 0xAD 0xDE
O C # 7.0 agora possui literais binários, o que é incrível.
[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
}
Como o tópico parece ter se voltado para declarar valores de sinalizadores baseados em bits em enumerações, pensei que valeria a pena apontar um truque útil para esse tipo de coisa. O operador de deslocamento à esquerda ( <<
) permitirá que você pressione um pouco para uma posição binária específica. Combine isso com a capacidade de declarar valores de enum em termos de outros valores da mesma classe e você terá uma sintaxe declarativa muito fácil de ler para enumerações de sinalizadores de 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
}
Somente número inteiro e hexadecimal diretamente, receio (ECMA 334v4):
9.4.4.2 Literais inteiros Literais inteiros são usados para escrever valores dos tipos int, uint, long e ulong. Literais inteiros têm duas formas possíveis: decimal e hexadecimal.
Para analisar, você pode usar:
int i = Convert.ToInt32("01101101", 2);
Adicionando à resposta do @ StriplingWarrior sobre sinalizadores de bits em enumerações, existe uma convenção fácil que você pode usar em hexadecimal para contagem crescente nos turnos de bits. Use a sequência 1-2-4-8, mova uma coluna para a esquerda e 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
}
Digitalize para baixo começando com a coluna da direita e observe o padrão 1-2-4-8 (shift) 1-2-4-8 (shift) ...
Para responder à pergunta original, eu segundo a sugestão de @ Sahuagin de usar literais hexadecimais. Se você estiver trabalhando com números binários com frequência suficiente para que isso seja uma preocupação, vale a pena tentar entender o hexadecimal.
Se você precisar ver números binários no código-fonte, sugiro adicionar comentários com literais binários, como eu tenho acima.
Você sempre pode criar quase literais, constantes que contêm o valor que você procura:
const int b001 = 1;
const int b010 = 2;
const int b011 = 3;
// etc ...
Debug.Assert((b001 | b010) == b011);
Se você usá-los frequentemente, poderá agrupá-los em uma classe estática para reutilização.
No entanto, um pouco fora do tópico, se você tiver alguma semântica associada aos bits (conhecida em tempo de compilação), sugiro usar um Enum:
enum Flags
{
First = 0,
Second = 1,
Third = 2,
SecondAndThird = 3
}
// later ...
Debug.Assert((Flags.Second | Flags.Third) == Flags.SecondAndThird);
Se você observar o status de implementação do recurso de idioma da .NET Compiler Platform ("Roslyn"), poderá ver claramente que no C # 6.0 esse é um recurso planejado; portanto, na próxima versão, podemos fazê-lo da maneira usual.
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 isso, para binário de 8 bits, eu uso isso para criar uma classe estática e a coloca na área de transferência. Em seguida, ela é colada no projeto e adicionada à seção Usando, para que qualquer coisa com nb001010 seja retirada de uma tabela, em menos estático, mas ainda assim ... eu uso C # para muitos códigos gráficos PIC e uso 0b101010 muito no Hi-Tech C
--sample do 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
O recurso literal binário não foi implementado no C # 6.0 e no Visual Studio 2015. mas, em 30 de março de 2016, a Microsoft anunciou a nova versão do Visual Studio '15' Preview com a qual podemos usar literais binários.
Podemos usar um ou mais de um caractere Sublinhado (_) para separadores de dígitos. então o trecho de código seria algo como:
int x = 0b10___10_0__________________00; //binary value of 80
int SeventyFive = 0B100_________1011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
e podemos usar 0b e 0B, como mostrado no snippet de código acima.
se você não quiser usar o separador de dígitos, poderá usá-lo sem separador de dígitos, como o trecho de código abaixo
int x = 0b1010000; //binary value of 80
int SeventyFive = 0B1001011; //binary value of 75
WriteLine($" {x} \n {SeventyFive}");
Embora não seja possível usar um Literal, talvez um BitConverter também possa ser uma solução?
BitConverter.IsLittleEndian
, o qual você pode usar para testar (e reverter um buffer) se a máquina host não for muito pequena.
Embora a solução de análise de strings seja a mais popular, não gosto, porque a análise de strings pode ser um ótimo desempenho em algumas situações.
Quando é necessário um tipo de campo de bits ou máscara binária, prefiro escrever como
bitMask longo = 1011001;
E depois
int bit5 = BitField.GetBit (bitMask, 5);
Ou
bool flag5 = BitField.GetFlag (bitMask, 5); `
Onde a 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;
}
}
Basicamente, acho que a resposta é NÃO, não há uma maneira fácil. Use constantes decimais ou hexadecimais - elas são simples e claras. A resposta do @RoyTinkers também é boa - use um comentário.
int someHexFlag = 0x010; // 000000010000
int someDecFlag = 8; // 000000001000
As outras respostas aqui apresentam várias rodadas úteis, mas acho que não são melhores do que a resposta simples. Os designers de linguagem C # provavelmente consideraram um prefixo '0b' desnecessário. O HEX é fácil de converter em binário, e a maioria dos programadores precisará conhecer os equivalentes DEC de 0 a 8 de qualquer maneira.
Além disso, ao examinar valores no depurador, eles serão exibidos com HEX ou DEC.
if (a == MaskForModemIOEnabled)
vez deif (a == 0b100101)