Zeile 294 von java.util.Random Quelle sagt
if ((n & -n) == n) // i.e., n is a power of 2
// rest of the code
Warum ist das?
java
logic
bit-manipulation
David Weng
quelle
quelle
(n & (n - 1)) == 0
funktioniert auch (sie entfernt das Bit niedrigster Ordnung, wenn keine Bits mehr vorhanden sind, wurde zuerst höchstens 1 Bit gesetzt).Antworten:
Die Beschreibung ist nicht ganz korrekt, da
(0 & -0) == 0
0 keine Zweierpotenz ist. Ein besserer Weg, es zu sagen, ist((n & -n) == n)
wenn n eine Zweierpotenz oder das Negativ einer Zweierpotenz oder Null ist.Wenn n eine Zweierpotenz ist, ist n in binär eine einzelne 1, gefolgt von Nullen. -n im Zweierkomplement ist die Umkehrung + 1, so dass die Bits so ausgerichtet sind
Um zu sehen, warum diese Arbeit funktioniert, betrachten Sie das Zweierkomplement als invers + 1,
-n == ~n + 1
da Sie die eine vollständig durchtragen, wenn Sie eine hinzufügen, um die Ergänzung der beiden zu erhalten.
Wenn n etwas anderes als eine Zweierpotenz wäre †, würde das Ergebnis ein wenig fehlen, da das Zweierkomplement aufgrund dieses Übertrags nicht das höchste gesetzte Bit hätte.
† - oder Null oder ein Negativ einer Zweierpotenz ... wie oben erläutert.
quelle
(0 & -0) == 0
, der unmittelbar vorhergehende Aussage istif (n <= 0) throw ...
. Dies bedeutet, dass die zu testende Zahl zu diesem Zeitpunkt niemals 0 (oder negativ) sein wird.Random.java
die ich nicht gelesen habe.n
handelt. Ich habe diese Annahme nicht überprüft, bezweifle aber irgendwie, dass sich adouble
genauso verhalten würde.n
da diese Frage das "Java" -Tag hat.&
ist nicht aufdouble
oderfloat
in Java definiert. Es ist nur für Integer-Typen und Boolesche Werte definiert. Da dies-
nicht für Boolesche Werte definiert ist, können wir sicher schließen, dass diesn
ein integraler Bestandteil ist.Denn in 2er Komplement
-n
ist~n+1
.Wenn
n
eine Potenz von 2 ist, ist nur ein Bit gesetzt. Also~n
sind alle Bits außer diesem gesetzt. Wenn Sie 1 hinzufügen, setzen Sie das spezielle Bit erneut und stellen sicher, dassn & (that thing)
es gleich istn
.Das Umgekehrte gilt auch, weil 0 und negative Zahlen in der vorherigen Zeile dieser Java-Quelle ausgeschlossen wurden. Wenn
n
mehr als ein Bit gesetzt ist, ist eines davon das höchste dieser Art. Dieses Bit wird von nicht gesetzt,+1
da es ein niedrigeres klares Bit gibt, um es zu "absorbieren":quelle
Sie müssen die Werte als Bitmaps betrachten, um festzustellen, warum dies der Fall ist:
Nur wenn beide Felder 1 sind, wird eine 1 ausgegeben.
Jetzt macht -n eine 2er-Ergänzung. Es ändert alles
0
in1
und es fügt 1 hinzu.jedoch
Nur für Potenzen von 2 wird
(n & -n)
n sein.Dies liegt daran, dass eine Potenz von 2 als ein einzelnes gesetztes Bit in einem langen Meer von Nullen dargestellt wird. Die Negation ergibt genau das Gegenteil, eine einzelne Null (an der Stelle, an der sich die 1 befand) in einem Meer von Einsen. Durch Hinzufügen von 1 werden die unteren in den Bereich verschoben, in dem sich die Null befindet.
Und das bitweise und (&) filtert die 1 erneut heraus.
quelle
In der Zweierkomplementdarstellung besteht das Einzigartige an Zweierpotenzen darin, dass sie aus allen 0 Bits bestehen, mit Ausnahme des k-ten Bits, wobei n = 2 ^ k:
Um einen negativen Wert im Zweierkomplement zu erhalten, drehen Sie alle Bits um und fügen eins hinzu. Für Zweierpotenzen bedeutet dies, dass Sie links eine Reihe von Einsen bis einschließlich des 1-Bits erhalten, das sich im positiven Wert befand, und dann rechts eine Reihe von Nullen:
Sie können leicht erkennen, dass das Ergebnis der Spalten 2 und 4 mit dem der Spalte 2 übereinstimmen wird.
Wenn Sie sich die anderen Werte ansehen, die in dieser Tabelle fehlen, können Sie sehen, warum dies nur für die Zweierpotenzen gilt:
n & -n hat (für n> 0) immer nur 1 Bit gesetzt, und dieses Bit ist das niedrigstwertige gesetzte Bit in n. Für alle Zahlen, die Zweierpotenzen sind, ist das niedrigstwertige gesetzte Bit das einzige gesetzte Bit. Für alle anderen Zahlen ist mehr als ein Bit gesetzt, von denen im Ergebnis nur die niedrigstwertige gesetzt wird.
quelle
Es ist Eigentum von Zweierpotenzen und deren Zweierkomplement .
Nehmen Sie zum Beispiel 8:
Berechnung des Zweierkomplements:
Bei Potenzen von 2 wird nur ein Bit gesetzt, so dass durch Hinzufügen das n- te Bit von 2 n gesetzt wird (dasjenige wird weiter zum n- ten Bit übertragen). Wenn Sie dann
AND
die beiden Zahlen, erhalten Sie das Original zurück.Bei Zahlen, die keine Zweierpotenzen sind, werden andere Bits nicht umgedreht, sodass die
AND
nicht die ursprüngliche Zahl ergibt.quelle
Wenn n eine Potenz von 2 ist, bedeutet dies einfach, dass nur ein Bit auf 1 gesetzt ist und die anderen Nullen sind:
und weil
-n
ein 2er-Komplement von istn
(das bedeutet, dass das einzige Bit, das 1 ist, so bleibt, wie es ist, und die Bits auf der linken Seite dieses Bits auf 1 sitzen, was eigentlich keine Rolle spielt, da das Ergebnis des AND-Operators&
0 ist, wenn eines der beiden Bits ist Null):quelle
Beispiel gezeigt:
8 in hex = 0x000008
-8 in hex = 0xFFFFF8
8 & -8 = 0x000008
quelle