¿Qué significa "(int) value & 0x1, (int) value & 0x2, (int) value & 0x4, (int) value & 0x8" significa? "

11

código

El "valor" varía de 0 a 15 (sus posibles valores). ¿Cuándo se cumplirán esas 4 condiciones "si"? Si mi (int) valor = 2, ¿significa esto 0010?

            if  ((int)value & 0x1) 
            {
                //statement here
            }
            if  ((int)value & 0x2) 
            {
                //statement here
            }
            if  ((int)value & 0x4) 
            {
                //statement here
            }
            if  ((int)value & 0x8) 
            {
                //statement here
            }
Sean McCarthy
fuente
3
Esas son máscaras de bits que buscan bits individuales de value(leer if(value & 0x4)como "Es el 3er bit del valueconjunto (= 1)). Como aparentemente tiene problemas para entender el código, supongo que no es suyo. Esto (y el hecho de que no está preguntando para su revisión) hace que esta pregunta fuera del tema de CR.SE .
Nadie
Para una mejor comprensión, el código similar que se ha portado a C # utilizará el Enum.HasFlagmétodo para probar bits. Ver: Enum.HasFlag .
rwong

Respuestas:

12

Cada número se puede expresar como si value = b0*2^0 + b1*2^1 + b2*2^2 + b3*2^3 + ...cada b fuera uno 0o 1(estos son los bits de la representación). Esta es la representación binaria.

El binario AND ( &) toma cada uno de esos bpares sabios y realiza AND en ellos. Esto tiene las siguientes salidas:

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

Usando potencias de 2 (que tienen solo un bit) podemos aislar y probar los bits individuales:

  • value & 1es verdadero cuando valuees impar {1, 3, 5, 7, 9, 11, 13, 15}.

  • value & 2es verdadero cuando value/2es impar {2, 3, 6, 7, 10, 11, 14, 15}.

  • value & 4es verdadero cuando value/4es impar {4, 5, 6, 7, 12, 13, 14, 15}.

  • value & 8es verdadero cuando value/8es impar {8, 9, 10, 11, 12, 13, 14, 15}.

El prefijo 0x en los números significa que debe interpretarse como un número hexadecimal . Es un poco superfluo cuando solo sube a 0x8, pero le dice a los mantenedores que probablemente se use como una máscara de bits.

monstruo de trinquete
fuente
1
La redacción puede sugerir que puede extenderse a todos los números, lo que no es cierto: 8/6es impar, mientras que 8&6produce falso.
Sjoerd
@Sjoerd por eso dije "poderes de 2"
fanático del trinquete el
5

Estas sentencias if comprueban si se establece un bit específico de value.

El valor hexadecimal 0x4, por ejemplo, tiene el tercer bit del conjunto correcto a 1y todos los demás bits establecidos a 0. Cuando utiliza el operador binario y ( &) con dos operantes, el resultado tendrá todos los bits configurados a 0excepción de aquellos bits que son 1 en ambos operantes.

Entonces, cuando haces el cálculo value & 0x4, obtienes binario 00000000o binario 00000100, dependiendo de si el tercer bit de valuees 1o no 0. El primero se evalúa en false, y el segundo en true, por lo que el bloque if solo se ejecuta para valores donde se establece el tercer bit.

Philipp
fuente
1

Hay dos cosas interesantes a tener en cuenta aquí.

Primero, este es un patrón común para verificar cada uno de los 4 bits de orden inferior de un valor integral. La condición if se cumple si se establece el bit correspondiente. Para el valor 2, el patrón de bits es de hecho 0010.

La otra pregunta más interesante es ¿por qué el (int)elenco? Además del mal estilo de usar C-casts en C ++, ningún valor entero o de caracteres requiere este elenco. Un bool no tiene sentido, un doble / flotante se convertiría en un entero temporal y sería inusual usar valores literales para probar una enumeración. Puede tener sentido con un puntero, pero ese sería un uso muy especializado. Conclusión: el elenco no tiene sentido.

david.pfx
fuente