Use constantes e dê a eles nomes próprios; o fato de você precisar escrevê-los em decimal não deve importar. Pessoalmente, eu gostaria de ler em if (a == MaskForModemIOEnabled)vez deif (a == 0b100101)
Os dois conselhos são muito bons, exceto ao definir os referidos campos de bits, onde essas definições constantes nomeadas podem ser mais fáceis de ler e escrever com um literal binário. [Flags] enum Quantidade {None = 0, One = 1, Some = 0b10, Most = 0b100, Todos = 0b111}
É bom lembrar que os literais binários do C # são big-endian, mas em números inteiros x86 são little-endian, portanto Int16 = 0b0010_0110_0000_0011serão armazenados como { 0b0000_0011, 0b0010_0110 }- confusos.
Dai
1
@ Dai que não é diferente de literais hexadecimais. Em outras palavras, todas as constantes são big endian, mas armazenadas pouco endian na Intel / AMD e na maioria dos ARMs. 0xDEADBEEFserá armazenado como0xEF 0xBE 0xAD 0xDE
Cole Johnson
170
Atualizar
O C # 7.0 agora possui literais binários, o que é incrível.
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.
@ ColeJohnson: Muitos desenvolvedores preferem isso. Não sou tão bom em converter hexadecimal na minha cabeça quanto alguns desenvolvedores, e às vezes é melhor atender ao menor denominador comum.
usar o seguinte
2
Eu acho que essa é a maneira mais eficaz, pois as enums são construídas como constantes. Com o atributo [Flags] opcional, eles podem ser usados em operações bit a bit (não diretamente relacionadas à pergunta, mas particularmente úteis ao descrever literais binários). Outra possibilidade interessante é forçar o tipo de enum como um tipo interno (neste exemplo, adicione ': byte' após 'Days'); ver built-in tipos de bit.ly/MKv42E
caligari
Isso é realmente muito fácil de ler, embora declarando a 0 bandeira em um Enum é bastante má prática
miket
5
@ MikeT: Você pode elaborar (ou fornecer um link que elabore) esse último pensamento? Costumo declarar enumerações que começam com "1" porque quero ser capaz de detectar e apresentar falhas quando um valor simplesmente nunca foi inicializado. Mas há algumas situações em que um valor padrão realmente faz sentido, e eu acho que não haveria nada de errado em adicionar um nome para esse valor.
usar o seguinte
3
@MikeT De ca1008 : "Se uma enumeração que tenha o FlagsAttribute aplicado definir um membro com valor zero, seu nome deverá ser 'Nenhum' para indicar que nenhum valor foi definido na enumeração." Portanto, é perfeitamente válido adicioná-lo para servir como valor padrão, se for chamado "Nenhum". No geral, parece-me mais claro se o valor em um campo inicializado por padrão realmente tem um nome para mostrar.
Nyerguds
115
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.
Como uma atualização para esta resposta, com as últimas informações modernas de ponta (julho de 2014); O C # 6.0 apresenta literais binários. Veja a minha resposta atualizados wayyyyyy baixo na parte inferior ...
BTownTKD
1
@BTownTKD, sua resposta está realmente no topo :), pois é a resposta aceita.
RBT
25
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.
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.
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
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 80intSeventyFive=0B100_________1011;//binary value of 75WriteLine($" {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 80intSeventyFive=0B1001011;//binary value of 75WriteLine($" {x} \n {SeventyFive}");
O BitConverter fica um pouco complicado porque é endia-máquina; e na sua Intel padrão, isso significa pouco endian. A maioria das pessoas tem dificuldade em ler literais little-endian ...
Marc Gravell
1
Ai, agora eu me lembro por que eu estava sempre ciente, mas nunca usei o BitConverter ...
Michael Stum
4
O BitConverter possui o campo BitConverter.IsLittleEndian, o qual você pode usar para testar (e reverter um buffer) se a máquina host não for muito pequena.
foxy
1
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
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;// 000000010000int 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)
Respostas:
O C # 7.0 suporta literais binários (e separadores de dígitos opcionais por meio de caracteres sublinhados).
Um exemplo:
Você também pode encontrar mais informações na página do Roslyn GitHub .
fonte
Int16 = 0b0010_0110_0000_0011
serão armazenados como{ 0b0000_0011, 0b0010_0110 }
- confusos.0xDEADBEEF
será armazenado como0xEF 0xBE 0xAD 0xDE
Atualizar
O C # 7.0 agora possui literais binários, o que é incrível.
Correio Original
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.fonte
Somente número inteiro e hexadecimal diretamente, receio (ECMA 334v4):
Para analisar, você pode usar:
fonte
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.
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.
fonte
Você sempre pode criar quase literais, constantes que contêm o valor que você procura:
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:
fonte
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.
fonte
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--
:-) NEAL
fonte
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:
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
fonte
Embora não seja possível usar um Literal, talvez um BitConverter também possa ser uma solução?
fonte
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
E depois
Ou
Onde a classe BitField é
fonte
Você pode usar
0b000001
desde o Visual Studio 2017 (C # 7.0)fonte
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.
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.
fonte