Usa constantes y dales nombres propios, entonces el hecho de que tengas que escribirlas en decimal no debería importar. Personalmente, me gustaría leer en if (a == MaskForModemIOEnabled)lugar deif (a == 0b100101)
Ambos son muy buenos consejos, excepto cuando se definen dichos campos de bits, donde estas definiciones constantes con nombre pueden ser más fáciles de leer y escribir con un literal binario. [Indicadores] enum Cantidad {Ninguno = 0, Uno = 1, Algunos = 0b10, La mayoría = 0b100, Todos = 0b111}
Es útil recordar que los literales binarios de C # son big-endian, pero en x86 los enteros son little-endian, por Int16 = 0b0010_0110_0000_0011lo que se almacenarán como { 0b0000_0011, 0b0010_0110 }confusos.
Dai
1
@Dai no es diferente de los literales hexadecimales. En otras palabras, todas las constantes son big endian, pero se almacenan little endian en Intel / AMD y la mayoría de los ARM. 0xDEADBEEFserá almacenado como0xEF 0xBE 0xAD 0xDE
Cole Johnson
170
Actualizar
C # 7.0 ahora tiene literales binarios, lo cual es increíble.
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.
@ColeJohnson: Muchos desarrolladores prefieren eso. No soy tan bueno para convertir hexadecimal en mi cabeza como lo son algunos desarrolladores, y a veces es mejor atender al mínimo común denominador.
StriplingWarrior
2
Creo que esta es la forma más efectiva ya que las enumeraciones se crean como constantes. Con el atributo opcional [Flags] pueden usarse en operaciones bit a bit (no directamente relacionadas con la pregunta, pero particularmente útiles cuando se describen literales binarios). Otra posibilidad interesante es forzar el tipo de enumeración como un tipo incorporado (en este ejemplo, agregue ': byte' después de 'Días'); ver tipos incorporados en bit.ly/MKv42E
caligari
En realidad, eso es muy fácil de leer, aunque declarar una
marca de
55
@MikeT: ¿Puedes elaborar (o proporcionar un enlace que explique) en ese último pensamiento? A menudo declaro enumeraciones que comienzan con "1" porque quiero poder detectar y fallar rápidamente cuando un valor simplemente nunca se inicializó. Pero hay algunas situaciones en las que un valor predeterminado realmente tiene sentido, y creo que no habría nada de malo en agregar un nombre para ese valor.
StriplingWarrior
3
@MikeT De ca1008 : "Si una enumeración que tiene el atributo FlagsAttribute aplicado define un miembro de valor cero, su nombre debe ser 'Ninguno' para indicar que no se han establecido valores en la enumeración". Por lo tanto, es perfectamente válido agregarlo para que sirva como valor predeterminado, si se llama "Ninguno". En general, me parece más claro si el valor en un campo inicializado por defecto realmente tiene un nombre para mostrar.
Nyerguds
115
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.
Como una actualización de esta respuesta, con la última información moderna de vanguardia (julio de 2014); C # 6.0 introduce literales binarios. Vea mi respuesta actualizada wayyyyyy en la parte inferior ...
BTownTKD
1
@BTownTKD su respuesta está realmente en la parte superior :), ya que es la respuesta aceptada.
RBT
25
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.
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.
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:
enumFlags{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
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 80intSeventyFive=0B100_________1011;//binary value of 75WriteLine($" {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 80intSeventyFive=0B1001011;//binary value of 75WriteLine($" {x} \n {SeventyFive}");
BitConverter se vuelve un poco complicado porque es machine-endian; y en su Intel estándar, eso significa little-endian. La mayoría de las personas tienen dificultades para leer literales little-endian ...
Marc Gravell
1
Ay, ahora recuerdo por qué siempre fui consciente pero nunca usé el BitConverter ...
Michael Stum
44
BitConverter tiene el campo BitConverter.IsLittleEndian, que puede usar para probar (y revertir un búfer) si la máquina host no es poco endian.
astuto
1
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
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;// 000000010000int 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)
Respuestas:
C # 7.0 admite literales binarios (y separadores de dígitos opcionales mediante caracteres de subrayado).
Un ejemplo:
También puede encontrar más información en la página de Roslyn GitHub .
fuente
Int16 = 0b0010_0110_0000_0011
lo que se almacenarán como{ 0b0000_0011, 0b0010_0110 }
confusos.0xDEADBEEF
será almacenado como0xEF 0xBE 0xAD 0xDE
Actualizar
C # 7.0 ahora tiene literales binarios, lo cual es increíble.
Publicación original
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.fuente
Solo entero y hexadecimal directamente, me temo (ECMA 334v4):
Para analizar, puede usar:
fuente
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.
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.
fuente
Siempre puede crear cuasi literales, constantes que contengan el valor que busca:
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:
fuente
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.
fuente
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--
:-) NEAL
fuente
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í:
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
fuente
Si bien no es posible usar un Literal, ¿tal vez un BitConverter también puede ser una solución?
fuente
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
Y después
O
Donde está la clase BitField
fuente
Puede usar
0b000001
desde Visual Studio 2017 (C # 7.0)fuente
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.
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.
fuente