Domanda

Ho questi possibili flag di bit.

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

Quindi, ogni numero è come una vera e propria dichiarazione falsa / sul lato server. Quindi, se i primi 3 elementi, e solo i primi 3 articoli sono contrassegnati "vero" sul lato server, il servizio di web restituirà un 7. Se tutti i 14 articoli di cui sopra sono vere, mi sarebbe ancora ottenere un numero singolo di ritorno dal servizio web che è è la somma di tutti quei numeri.

Qual è il modo migliore per gestire il numero di torno per scoprire quali elementi sono contrassegnati come "vera"?

È stato utile?

Soluzione

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

}

Altri suggerimenti

Usa un operatore di mascheramento di bit. Nel linguaggio C:

 X & 8

è vero, se è impostato il "8" bit s.

È possibile enumerare le maschere di bit, e contare quanti sono impostati.

Se è davvero il caso che l'intera parola contiene bit, e si desidera semplicemente calcolare quanti bit sono impostati, si vuole in sostanza un "conteggio della popolazione". l'assoluto modo più veloce per ottenere un conteggio della popolazione è quello di eseguire un "POPCNT" nativo di solito disponibili in set di istruzioni della macchina.

Se non si cura di spazio, è possibile impostare un array countedbits [...] indicizzato dal valore con i conteggi bit precalcolate. Poi un singolo accesso alla memoria calcola il valore del bit.

Spesso usato è semplicemente "codice bit giocherellando" che calcola bit conta :

(il metodo di 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
}

(parallelo bit summming, 32 bit)

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

Se non avete visto gli hack po mani in prima, siete dentro per un ossequio.

PHP, essere divertente, può fare cose divertenti con un po 'di questa aritmetica.

Il pensiero la domanda è vecchia potrebbe aiutare qualcun altro. Sto mettendo i numeri in binario come la sua più chiara per capire. Il codice non era stato testato, ma spero la logica è chiara. Il codice è PHP specifico.

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;
}

Utilizzo:

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

Un modo sarebbe ciclo tra il proprio numero, sinistra-shifting (cioè dividere per 2) e confrontare il primo bit con 1 usando l'& operando.

Poiché non v'è alcuna risposta definitiva con il codice PHP, aggiungo questo esempio di lavoro:

// 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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top