Christian Seiler: Bit Operationen

Beitrag lesen

Hallo Alex,

10010010101111111111110111111010

Nach dem Verschieben der Bits erhalte ich aber:

11100100101011111111111101111110

Das sieht für mich nun wiederum nicht richtig aus. So wie ich es verstanden habe, müssten alle Bits um 2 Stellen nach rechts geschoben werden. Dann ist es ja eigentlich unmöglich, dass plötzlich Einsen auf der linken Seite erscheinen.

Doch - da es sich bei PHP immer um "signed integers" handelt (d.h. Ganzzahlen mit Vorzeichen), wird beim Rechts-Shift immer das höherwertigste Bit "reingeshiftet". Wenn das 0 ist, wird 0 reingeshiftet, wenn's 1 ist, 1.

Deine Zahl ist nun 32bit lang. Auf 32bit-Systemen ist bei PHP int so groß. Daher ist das höchste Bit bei Dir wirklich 1.

Seth hat ein 64bit-System, d.h. bei ihm sind nochmal 32bit 0en, die aber ausgelassen werden. Daher klappt es bei ihm scheinbar, bei Dir nicht.

Wenn Du willst, dass *immer* geshiftet wird, als wären es Zahlen ohne Vorzeichen, musst Du Dir das selbst programmieren:

// shifte $i um $n nach rechts, fülle mit 0 auf  
function ushr ($i, $n) {  
  // wenn höchstes bit gesetzt ist  
  if ($i & 0x80000000) {  
    // um 1 shiften  
    $i = $i >> 1;  
    // höchstes bit auf 0 setzen  
    $i = $i & 0x4FFFFFFF;  
    // um den rest shiften  
    return $i >> ($n - 1);  
  } else {  
    // klappt ohne probleme  
    return $i >> $n;  
  }  
}

Das funktioniert dann sowohl auf 32bit- als auch auf 64bit-Systemen, auf 64bit-Systemen ist halt der Zwischenschritt "höchstes bit auf 0 setzen" nicht erforderlich, schadet aber auch nicht.

Viele Grüße,
Christian