Effizienteste Weg, um Extrakt Bitflags
Frage
Ich habe diese möglichen Bitflags.
1, 2, 4, 8, 16, 64, 128, 256, 512, 2048, 4096, 16384, 32768, 65536
So jede Zahl ist wie eine wahr / falsch Aussage auf der Serverseite. Also, wenn die ersten drei Elemente, und nur die ersten drei Elemente markiert sind „true“ auf der Serverseite wird der Webservice eine 7. Rückkehr Oder wenn alle 14 oben genannten Punkte erfüllt sind, würde ich immer noch eine einzige Zahl zurück aus der get Web-Service, der die Summe aller dieser Zahlen ist.
Was ist der beste Weg, um die Zahl, die ich zurück zu handhaben, um herauszufinden, welche Elemente sind markiert als „wahr“?
Lösung
if (7 & 1) { // if bit 1 is set in returned number (7)
}
Andere Tipps
Verwenden Sie ein bisschen Maskierungsoperator. In der C-Sprache:
X & 8
wahr ist, wenn der "8" s-Bit gesetzt ist.
Sie können die Bitmasken aufzählen, und zählen, wie viele eingestellt sind.
Wenn es wirklich der Fall ist, dass das gesamte Wort Bits enthält, und Sie wollen einfach berechnen, wie viele Bits gesetzt sind, können Sie im Grunde wollen eine „Bevölkerungszahl“. Das Absolute schnellste Weg, um eine Bevölkerungszahl zu erhalten, ist eine native „popcnt“ in der Regel ausführen in Ihrem Gerät Befehlssatz zur Verfügung.
Wenn Sie nicht über den Raum kümmern, können Sie ein Array countedbits eingerichtet [...] indiziert durch Ihren Wert mit vorberechneten Bit zählt. Dann wird ein einzelner Speicherzugriff berechnet Ihre Bitzahl.
Häufig verwendete einfach nur "Bit twiddling Code" dass berechnet Bitzählwerte :
(Kernigan Methode):
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
}
(parallel Bit summming, 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
Wenn Sie nicht den Bit-Fummel Hacks gesehen haben, sind Sie für eine Behandlung.
PHP, der lustig ist, kann mit einigen dieser Arithmetik lustige Dinge tun.
Thought die Frage ist alt helfen könnte jemand anderes. Ich stelle die Zahlen in binär als klarer zu verstehen. Der Code war nicht getestet, aber hoffen, dass die Logik ist klar. Der Code ist PHP-spezifisch.
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;
}
Verbrauch:
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
Ein Weg, um eine Schleife durch Ihre Zahl sein würde, links schieb es (dh Division durch 2) und vergleichen, um den ersten Bit mit 1 unter Verwendung der & Operanden.
Da es keine eindeutige Antwort mit PHP-Code, ich hinzufügen, um dieses Arbeitsbeispiel:
// 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;
}