Wie prüft diese bitweise Operation auf eine Potenz von 2?
Lesezeit: 5 Minuten
Ich schaue mir einen Code an, der trivial sein sollte – aber meine Mathematik versagt hier kläglich.
Hier ist eine Bedingung, die überprüft, ob eine Zahl eine Potenz von 2 ist, indem Folgendes verwendet wird:
if((num != 1) && (num & (num - 1))) { /* make num pow of 2 */ }
Meine Frage ist, wie bestimmt die Verwendung eines bitweisen AND zwischen num und num – 1, ob eine Zahl eine Potenz von 2 ist?
Weitere Informationen finden Sie unter dieser Frage: stackoverflow.com/questions/600293/…
– Greg Hewgill
27. Juni 2009 um 23:38 Uhr
Es kommt natürlich auf die Art an num – Die meisten Antworten hier gehen davon aus, dass es sich um einen ganzzahligen Typ ohne Vorzeichen handelt, bei dem die bitweisen Operationen genau definiert sind.
– Toby Speight
5. April 2017 um 14:39 Uhr
eduffy
Jede Potenz von 2 minus 1 ist alles Einsen: (2N – 1 = 111….b)
Dieser Ausdruck testet also, ob eine Zahl KEINE Potenz von 2 ist.
Eckfall, wenn 1.num=0 und num = -2147483648, wenn der Datentyp int ist und durch den Mindestwert begrenzt ist. Wenn num==0 ist, ist num keine Zweierpotenz
– Bhaskar13
14. August 2020 um 18:53 Uhr
Wie beweist diese Erklärung etwas? Es zeigt lediglich, dass eine Potenz von 2 produzieren würde 0 für den Ausdruck x & (x - 1)nicht umgekehrt.
– chqrlie
19. Februar um 15:17 Uhr
lavinio
Nun, der erste Fall prüft auf 20 == 1.
Für die anderen Fälle die num & (num - 1) kommt ins Spiel:
Das heißt, wenn Sie eine beliebige Zahl nehmen und die Bits von einer niedrigeren maskieren, erhalten Sie einen von zwei Fällen:
Wenn die Zahl bereits eine Zweierpotenz ist, führt eine Zahl weniger zu einer Binärzahl, bei der nur die niederwertigen Bits gesetzt sind. Verwenden & es wird nichts tun.
Beispiel mit 8: 0100 & (0100 - 1) –> (0100 & 0011) –> 0000
Wenn die Zahl nicht bereits eine Zweierpotenz ist, berührt eins weniger nicht das höchste Bit, also wird das Ergebnis sein wenigstens die größte Zweierpotenz kleiner als num.
Beispiel mit 3: 0011 & (0011 - 1) –> (0011 & 0010) –> 0010
Beispiel mit 13: 1101 & (1101 - 1) –> (1101 & 1100) –> 1100
Der tatsächliche Ausdruck findet also alles, was keine Zweierpotenz ist, einschließlich 20.
Eigentlich die Prüfung für den Spezialfall num==1 (2^0=1) wird nicht benötigt. Für diesen Fall ist (num & (num-1)) = (1 & 0) = 0 sowieso.
– farindk
8. Mai 2014 um 14:18 Uhr
Die Erklärung des zweiten Punktes ist falsch, (num – 1) könnte eine Zweierpotenz sein, muss es aber nicht. Der Grund, warum das Ergebnis immer ungleich Null ist, liegt darin, dass die Operation dies kann stets übertragen werden, ohne das höchste Bit zu berühren, und zumindest dieses Bit wird in der Ausgabe angezeigt.
– Ismael Luceno
18. Dezember 2014 um 20:53 Uhr
Der Kommentar von Ismael Luceno ist eine bessere Erklärung für diese Beobachtung
– Ketcomp
23. Juli 2016 um 18:17 Uhr
Wie in den Kommentaren oben erwähnt, ist die Aussage in Punkt 2: “die die höchste Potenz von 2 nicht größer als num zurückgibt”, falsch. Es sollte genauer lauten “was zurückkehrt wenigstens die höchste Potenz von 2 nicht größer als num”. Ich habe diese Antwort bearbeitet und wartet auf die Begutachtung durch Kollegen.
– xdavidliu
5. Juli 2018 um 0:05 Uhr
Toon Krijthe
Brunnen,
Wenn Sie X = 1000 haben, dann ist x-1 = 0111. Und 1000 && 0111 ist 0000.
Jede Zahl X, die eine Potenz von 2 ist, hat eine x-1, die Einsen an der Stelle hat, an der x Nullen hat. Und ein bitweises und von 0 und 1 ist immer 0.
Wenn die Zahl x keine Zweierpotenz ist, zum Beispiel 0110. Das x-1 ist 0101 und das und ergibt 0100.
Für alle Kombinationen innerhalb von 0000 – 1111 führt dies zu
Aber natürlich muss auf 0 geprüft werden, da 0 keine Potenz von 2 ist, aber es wird getestet, als ob es eine wäre.
– Steve Jessop
27. Juni 2009 um 21:58 Uhr
Ein paar Dinge hier – zuerst denke ich, dass Sie verwenden && ein paar Stellen, wo Sie meinten &. n && (n-1) wäre fast überall 1 (außer für n = 0 und n = 1, richtig?) Zweitens ist 1 eine Potenz von 2, aber das “Bedürfnis” hängt vom Kontext ab, den wir nie gesehen haben (“wahr, wenn die Macht positiv / natürlich ist” , oder umgekehrt „wahr, wenn genau ein Bit gesetzt ist“ usw.) Nichts Persönliches, das war sowieso fast ein Jahrzehnt her.
– Johannes P
19. Februar 2018 um 11:56 Uhr
Ich bevorzuge diesen Ansatz, der auf dem Zweierkomplement beruht:
Auch der angegebene Ausdruck betrachtet 0 als Potenz von 2. Um dies zu beheben, verwenden Sie !(x & (x - 1)) && x; stattdessen.
Nein das ist falsch. Es gibt kein x mit 2**x = 0. Also ist x keine Potenz von 2.
– Accipitridae
28. Juni 2009 um 13:29 Uhr
Toby Speight
Es bestimmt, ob Integer eine Potenz von 2 ist oder nicht. Wenn (x & (x-1)) Null ist, dann ist die Zahl eine Potenz von 2.
Lassen Sie zum Beispiel x 8 sein (1000 in binär); dann x-1 = 7 (0111).
if 1000
& 0111
---------------
0000
C-Programm zur Demonstration:
#include <stdio.h>
void main()
{
int a = 8;
if ((a&(a-1))==0)
{
printf("the bit is power of 2 \n");
}
else
{
printf("the bit is not power of 2\n");
}
}
Dies gibt aus the bit is power of 2.
#include <stdio.h>
void main()
{
int a = 7;
if ((a&(a-1))==0)
{
printf("the bit is power of 2 \n");
}
else
{
printf("the bit is not power of 2\n");
}
}
Dies gibt aus the bit is not power of 2.
Nein das ist falsch. Es gibt kein x mit 2**x = 0. Also ist x keine Potenz von 2.
– Accipitridae
28. Juni 2009 um 13:29 Uhr
Shobhit Srivastava
Angenommen, n ist die gegebene Zahl, wenn n eine Potenz von 2 ist (n && !(n & (n-1)) gibt 1 zurück, sonst 0
14134400cookie-checkWie prüft diese bitweise Operation auf eine Potenz von 2?yes
Weitere Informationen finden Sie unter dieser Frage: stackoverflow.com/questions/600293/…
– Greg Hewgill
27. Juni 2009 um 23:38 Uhr
Es kommt natürlich auf die Art an
num
– Die meisten Antworten hier gehen davon aus, dass es sich um einen ganzzahligen Typ ohne Vorzeichen handelt, bei dem die bitweisen Operationen genau definiert sind.– Toby Speight
5. April 2017 um 14:39 Uhr