number - Literais binários em C#




get binary number c# (8)

Existe uma maneira de escrever literais binários em C #, como o prefixo hexadecimal com 0x? 0b não funciona.

Se não, qual é a maneira mais fácil de fazer isso? Algum tipo de conversão de string?


Atualizar

C # 7.0 agora tem 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
}

Post original

Como o tópico parece ter se voltado para declarar valores de sinalizadores baseados em bits em enums, achei que valeria a pena apontar um truque útil para esse tipo de coisa. O operador left-shift ( << ) permitirá que você empurre um bit para uma posição binária específica. Combine isso com a capacidade de declarar valores enum em termos de outros valores na mesma classe, e você tem uma sintaxe declarativa muito fácil de ler para enums de flag 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
}

Adicionando à resposta do @StriplingWarrior sobre sinalizadores de bit em enums, há uma convenção fácil que você pode usar em hexadecimal para contar para cima nos turnos de bit. 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 a pergunta original, sugiro a sugestão do @ Sahuagin de usar literais hexadecimais. Se você está trabalhando com números binários com frequência suficiente para que isso seja uma preocupação, vale a pena pegar o jeito do hexadecimal.

Se você precisar ver números binários no código-fonte, sugiro adicionar comentários com literais binários, como acima.


Basicamente, acho que a resposta é NÃO, não há um caminho 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ários trabalhos úteis - uma rodada, mas acho que eles não são melhores do que a resposta simples. Os projetistas de linguagem C # provavelmente consideraram desnecessário o prefixo '0b'. HEX é fácil de converter em binário, e a maioria dos programadores terá que conhecer os equivalentes DEC de 0-8 de qualquer maneira.

Além disso, ao examinar valores no depurador, eles serão exibidos com HEX ou DEC.


Embora a solução de análise de string seja a mais popular, eu não gosto dela, porque a string de análise pode ser um ótimo hit de desempenho em algumas situações.

Quando é necessário um tipo de bitfield ou máscara binária, prefiro escrevê-lo 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;
    }
}

O C # 7.0 suporta literais binários (e separadores de dígitos opcionais via caracteres de sublinhado).

Um exemplo:

int myValue = 0b0010_0110_0000_0011;

Você também pode encontrar mais informações na página do Roslyn GitHub .


O recurso literal binário não foi implementado no C # 6.0 & 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ígito. então o snippet 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, conforme mostrado no snippet de código acima.

Se você não quiser usar o separador de dígitos, poderá usá-lo sem o separador de dígitos, como abaixo do snippet de código.

int x           = 0b1010000; //binary value of 80
int SeventyFive = 0B1001011; //binary value of 75

WriteLine($" {x} \n {SeventyFive}");

Você pode usar 0b000001 desde o Visual Studio 2017 (C # 7.0)


Você sempre pode criar quase-literais, constantes que contêm o valor que você está depois:

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

Se você usá-los com frequência, poderá envolvê-los em uma classe estática para reutilização.

No entanto, se você tiver alguma semântica associada aos bits (conhecida em tempo de compilação), sugiro usar um Enum em vez disso:

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






binary