c# - unity - ¿Por qué las enumeraciones de indicador generalmente se definen con valores hexadecimales?
enum flags unity (6)
Muchas veces veo declaraciones de enunciados de enunciado que usan valores hexadecimales. Por ejemplo:
[Flags]
public enum MyEnum
{
None = 0x0,
Flag1 = 0x1,
Flag2 = 0x2,
Flag3 = 0x4,
Flag4 = 0x8,
Flag5 = 0x10
}
Cuando declaro una enumeración, generalmente lo declaro así:
[Flags]
public enum MyEnum
{
None = 0,
Flag1 = 1,
Flag2 = 2,
Flag3 = 4,
Flag4 = 8,
Flag5 = 16
}
¿Hay alguna razón o razón de por qué algunas personas eligen escribir el valor en hexadecimal en lugar de decimal? Flag5 = 0x16
como lo veo, es más fácil confundirse al usar valores hexadecimales y accidentalmente escribir Flag5 = 0x16
lugar de Flag5 = 0x10
.
Creo que es solo porque la secuencia es siempre 1,2,4,8 y luego se agrega un 0.
Como puedes ver:
0x1 = 1
0x2 = 2
0x4 = 4
0x8 = 8
0x10 = 16
0x20 = 32
0x40 = 64
0x80 = 128
0x100 = 256
0x200 = 512
0x400 = 1024
0x800 = 2048
y así sucesivamente, siempre que recuerde la secuencia 1-2-4-8 puede construir todas las banderas siguientes sin tener que recordar los poderes de 2
Hace que sea fácil ver que estos son indicadores binarios .
None = 0x0, // == 00000
Flag1 = 0x1, // == 00001
Flag2 = 0x2, // == 00010
Flag3 = 0x4, // == 00100
Flag4 = 0x8, // == 01000
Flag5 = 0x10 // == 10000
Aunque la progresión lo hace aún más claro:
Flag6 = 0x20 // == 00100000
Flag7 = 0x40 // == 01000000
Flag8 = 0x80 // == 10000000
Las razones pueden ser diferentes, pero una ventaja que veo es que el hexadecimal te recuerda: "Bueno, ya no estamos lidiando con números en el mundo arbitrario de base diez inventado por humanos. Estamos lidiando con bits, el mundo de la máquina, y nosotros Jugaremos según sus reglas ". El hexadecimal se utiliza con poca frecuencia, a menos que se trate de temas de nivel relativamente bajo, donde el diseño de la memoria de los datos es importante. Usarlo insinúa el hecho de que esa es la situación en la que nos encontramos ahora.
Además, no estoy seguro acerca de C #, pero sé que en C x << y
es una constante válida en tiempo de compilación. El uso de cambios de bits parece ser el más claro:
[Flags]
public enum MyEnum
{
None = 0,
Flag1 = 1 << 0,
Flag2 = 1 << 1,
Flag3 = 1 << 2,
Flag4 = 1 << 3,
Flag5 = 1 << 4
}
Porque [Flags]
significa que la enumeración es realmente un bitfield . Con [Flags]
puede usar los operadores bit ( &
) y OR ( |
) para combinar las banderas. Cuando se trata de valores binarios como este, casi siempre es más claro usar valores hexadecimales. Esta es la razón por la que usamos hexadecimal en primer lugar. Cada carácter hexadecimal corresponde exactamente a un nibble (cuatro bits). Con decimal, este mapeo de 1 a 4 no es verdadero.
Porque es más fácil de seguir para los humanos donde los bits están en la bandera. Cada dígito hexadecimal puede caber en un binario de 4 bits.
0x0 = 0000
0x1 = 0001
0x2 = 0010
0x3 = 0011
... and so on
0xF = 1111
Por lo general, desea que sus banderas no se superpongan a los bits, la manera más fácil de hacerlo y visualizarlos es usar valores hexadecimales para declarar sus banderas.
Entonces, si necesita banderas con 16 bits, usará valores hexadecimales de 4 dígitos y así podrá evitar valores erróneos:
0x0001 //= 1 = 000000000000 0001
0x0002 //= 2 = 000000000000 0010
0x0004 //= 4 = 000000000000 0100
0x0008 //= 8 = 000000000000 1000
...
0x0010 //= 16 = 0000 0000 0001 0000
0x0020 //= 32 = 0000 0000 0010 0000
...
0x8000 //= 32768 = 1000 0000 0000 0000
Porque hay una forma mecánica y simple de duplicar una potencia de dos en hex. En decimal, esto es difícil. Requiere una larga multiplicación en tu cabeza. En hex, es un cambio simple. Puedes llevarlo hasta 1UL << 63
que no puedes hacer en decimal.