Pregunta

Tengo estos posibles indicadores de bits.

1, 2, 4, 8, 16, 64, 128, 256, 512, 2048, 4096, 16384, 32768, 65536

Así que cada número es como una verdadera declaración falsa / en el lado del servidor. Así que si los 3 primeros puntos, y sólo los 3 primeros artículos están marcados "verdadero" en el lado del servidor, el servicio web devolverán un 7. O si los 14 elementos anteriores son ciertas, todavía tendrían un único número de devolución de la servicio web que está es la suma de todos esos números.

¿Cuál es la mejor manera de manejar el número que regrese para saber qué artículos están marcados como "verdadera"?

¿Fue útil?

Solución

if (7 & 1) { // if bit 1 is set in returned number (7)

}

Otros consejos

Utilice un operador de bits de enmascaramiento. En el lenguaje C:

 X & 8

Es cierto, si se establece el bit s "8".

Puede enumerar las máscaras de bits, y contar cuántas son activados.

Si lo que realmente es el caso de que toda la palabra contiene bits, y desea simplemente calcular la cantidad de bits establecido, quiere, en esencia, un "recuento de la población". La absoluta forma más rápida de obtener un recuento de la población es la ejecución de un "POPCNT" nativo general disponibles en el conjunto de instrucciones de la máquina.

Si no se preocupan por el espacio, se puede configurar un array countedbits [...] indexado por su valor con el paso cuenta precalculados. A continuación, un único acceso a la memoria calcula el número de bits.

A menudo se utiliza es simplemente "código de bits haciendo girar" que calcula paso cuenta :

(método de Kernigan):

unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; c++)
{
  v &= v - 1; // clear the least significant bit set
}

(summming bits en paralelo, 32 bits)

v = v - ((v >> 1) & 0x55555555);                    // reuse input as temporary
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);     // temp
c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count

Si usted no ha visto los cortes poco haciendo girar antes, estás de enhorabuena.

PHP, siendo divertido, puede hacer cosas divertidas con un poco de esta aritmética.

El pensamiento la cuestión es poder ayudar a alguien más antigua. Estoy poniendo los números en binario como su más clara de entender. El código no había sido probado, pero espero que la lógica es clara. El código PHP es específica.

define('FLAG_A', 0b10000000000000);  
define('FLAG_B', 0b01000000000000);
define('FLAG_C', 0b00100000000000);
define('FLAG_D', 0b00010000000000);
define('FLAG_E', 0b00001000000000);
define('FLAG_F', 0b00000100000000);
define('FLAG_G', 0b00000010000000);
define('FLAG_H', 0b00000001000000);
define('FLAG_I', 0b00000000100000);
define('FLAG_J', 0b00000000010000);
define('FLAG_K', 0b00000000001000);
define('FLAG_L', 0b00000000000100);
define('FLAG_M', 0b00000000000010);
define('FLAG_N', 0b00000000000001);

function isFlagSet($Flag,$Setting,$All=false){
  $setFlags = $Flag & $Setting;
  if($setFlags and !$All) // at least one of the flags passed is set
     return true;
  else if($All and ($setFlags == $Flag)) // to check that all flags are set
     return true;
  else
     return false;
}

Uso:

if(isFlagSet(FLAG_A,someSettingsVariable)) // eg: someSettingsVariable = 0b01100000000010

if(isFlagSet(FLAG_A | FLAG_F | FLAG_L,someSettingsVariable)) // to check if atleast one flag is set

if(isFlagSet(FLAG_A | FLAG_J | FLAG_M | FLAG_D,someSettingsVariable, TRUE)) // to check if all flags are set

Una forma sería la de bucle a través de su número, a la izquierda de desplazamiento de ella (es decir se divide por 2) y comparar el primer bit con 1 usando el y operando.

Como no hay una respuesta definitiva con código php, añado este ejemplo de trabajo:

// returns array of numbers, so for 7 returns array(1,2,4), etc..

function get_bits($decimal) {
  $scan = 1;
  $result = array();
  while ($decimal >= $scan){
    if ($decimal & $scan) $result[] = $scan;
    $scan<<=1; 
  }
  return $result;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top