010
14.04.2007, 23:03 Uhr
0xdeadbeef
Gott (Operator)
|
OK, der Reihe nach: sizeof(long long) * 8 ist nur 32, wenn long long 4 byte lang ist, das ist richtig. An der Stelle wird dann nicht sichergestellt, dass long long 64 bit lang ist, sondern das Programm so umgestellt, dass es mit long long arbeitet, egal wie lang der Datentyp halt ist. long long muss nicht zwingend 64 bit lang sein - wie gesagt, im C++-Standard kommt er schonmal garnicht vor, und im C99-Standard ist lediglich festgelegt dass
C++: |
sizeof(long long) >= sizeof(long)
|
Die zeile
C++: |
src = (orig_num >> n) & 1;
|
isoliert das nte bit des Datentyps, vom LSB aus gezählt. Übrigens steht das nicht unbedingt rechts - je nachdem, wo das im Speicher platziert ist und wie du zum Rechner (bzw. dem betreffenden RAM-Baustein stehst) kann das vorne, hinten, links oder rechts sein. Bzw. ernsthaft - ob das LSB links oder rechts steht, ist eine Frage der Interpretation, und außerdem eine Frage des Bytesex. Da kann man lange drüber diskutieren. Wenn man die Bitshift-Operatoren als '>> nach rechts' und '<< nach links' versteht, ist das LSB allerdings rechts (die von Mathematikern bevorzuge Darstellung)
Zurück zum Code - was die Zeile bewirkt ist, 'wenn das nte bit gesetzt ist, 1, sonst 0'. Am Beispiel mit orig_num = 10, n = 1:
Code: |
00001010 == orig_num 00000101 == orig_num >> n 00000001 == (orig_num >> n) & 1
|
C++: |
dest = src << perm_[n];
|
schiebt das bit dann perm_[n] Stellen 'nach links' (GSB-wärts). Wenn das nte Bit in der ersten Zeile nicht gesetzt war, kommt dabei 0 raus, sonst 2 hoch perm_[n]. Beispiel fortgesetzt mit perm_[n] == 4
Code: |
00000001 == src 00010000 == src << perm_[n]
|
Und die Veroderung
C++: |
result = result | dest;
|
ist halt das Einfügen des Betreffenden Bits. Beispiel fortgesetzt, angenommen result war nach der ersten Iteration 64,
Code: |
01000000 == result 00010000 == dest 01010000 == result | dest
|
Wenn du perm_ in der anderen Richtung verstanden haben willst, musst du halt << und >> vertauschen. Und das funktioniert auch mit zufälligen Werten - allerdings kommt dabei keine Permutation raus, wenn perm_ einen Wert öfter als einmal enthält, oder Werte größer als die Länge des Datentyps.
Was das Bogus-Ergebnis betrifft, das ist wahrscheinlich schon richtig. In der IEEE-Darstellung von Integern ist das erste Bit das Vorzeichen, z.B. hat ein int8_t mit dem Bitmuster 11111111 den Wert -1. Versuchs mal mit unsigned long long, dann ist es wahrscheinlich intuitiver. -- Einfachheit ist Voraussetzung für Zuverlässigkeit. -- Edsger Wybe Dijkstra |