SELFPHP

SELFPHP-Druckversion
Original Adresse dieser Seite:
http://www.selfphp.de/praxisbuch/praxisbuchseite.php?site=117&group=24
© 2001-2017 E-Mail SELFPHP OHG, info@selfphp.de
© 2005-2017 E-Mail PHP5 Praxisbuch - Matthias Kannengiesser, m.kannengiesser@selfphp.de


Bit-Operatoren


Bitweise Operatoren wandeln Fließkommazahlen intern in 32-Bit-Ganzzahlen um. Welche Rechenoperation jeweils ausgeführt wird, hängt vom verwendeten Operator ab. In jedem Falle werden bei der Berechnung des Ergebniswerts jedoch die einzelnen Binärziffern (Bits) der 32-Bit-Ganzzahl unabhängig voneinander ausgewertet. Glücklicherweise werden Sie diese doch recht komplizierten Operatoren relativ selten bis gar nicht benötigen.

Ich will Ihnen jedoch die Vorzüge der Bitwise-Operatoren nicht vorenthalten. Die Bitwise-Operatoren werden von den meisten PHP-Entwicklern, wie bereits erwähnt, ignoriert, da sie es nicht gewohnt sind, binär zu arbeiten. Das Zahlensystem, welches nur zwei Werte kennt, nämlich 0 oder 1, ist einer Vielzahl von Entwicklern suspekt. Ich empfehle Ihnen jedoch, den Bitwise-Operatoren eine Chance zu geben.

Fallbeispiel – Rechner-Tuning

Stellen Sie sich vor, Sie betreiben einen Shop. In diesem bieten Sie das Tunen von Rechnern an (Aufrüstung).

Folgende Komponenten können nachgerüstet werden:

Nun könnten Sie zur Verwaltung dieser Komponenten pro Kunde Variablen verwenden, welche die Wünsche des Kunden berücksichtigen.

$extraHD = true;
$netzkarte = true;
$brenner = true;
$tvkarte = true;

Einen Nachteil besitzt dieser Ansatz: Wir benötigen für jede Komponente eine separate Variable, welche jeweils den booleschen Wert

speichert.

Dies bedeutet natürlich auch, dass jede Variable Speicherplatz in Anspruch nimmt. Genau hierfür eignet sich hervorragend der Einsatz von Bitwise-Operatoren.

Diese ermöglichen die Verwaltung von Daten auf binärer Ebene und lassen sich hervorragend kombinieren, sodass Sie nicht mehr vier Variablen benötigen, sondern lediglich eine – Sie haben richtig gelesen, eine!
Hinweis: Dies schont den Speicher und ist vor allem um einiges schneller in der Verarbeitung, da Sie auf der untersten Ebene mit Ihrem Computer kommunizieren, sozusagen Maschinencode schreiben, denn die binäre Ebene kennt nur 0/1.


Bit-Programmierung in die Praxis umsetzen

Sie sollten sich zuerst im Klaren darüber sein, wie Ihr Computer Prozesse verarbeitet. In PHP gibt es die Möglichkeit, über die Bitwise-Operatoren diese Ebene zu ereichen und zu nutzen.

Ein binärer Zahlenwert wird in Zahlensequenzen von Nullen und Einsen gespeichert. Die Basis in diesem binären Zahlensystem liegt bei 2. Um dieses Zahlensystem an unser Dezimalzahlensystem (mit Basis 10) anzupassen, müssen Sie die Beziehung zwischen beiden Systemen kennen. Hier einige binäre Zahlensequenzen, welche in Dezimalsequenzen umgewandelt werden, auf der linken Seite binär und auf der rechten dezimal (inkl. Umrechnung):

1 Bit 1 // 1: (1 x 1) = 1
2 Bit 10 // 2: (1 x 2) + (0 x 1) = 2
2 Bit 11 // 3: (1 x 2) + (1 x 1) = 3
3 Bit 100 // 4: (1 x 4) + (0 x 2) + (0 x 1) = 4
4 Bit 1000 // 8: (1 x 8) + (0 x 4) + (0 x 2) + (0 x 1) = 8
4 Bit 1001 // 9: (1 x 8) + (0 x 4) + (0 x 2) + (1 x 1) = 9
4 Bit 1100 // 12: (1 x 8) + (1 x 4) + (0 x 2) + (0 x 1) = 12
4 Bit 1111 // 15: (1 x 8) + (1 x 4) + (1 x 2) + (1 x 1) = 15
6 Bit 111111 // 63: (1 x 32) + (1 x 16) + (1 x 8) + (1 x 4) + (1 x 2) + (1 x 1) = 63

Wie Sie sehen, ist die Beziehung recht einfach, wenn man sich einmal die Umrechnung vor Augen hält. Immer wenn der binären Zahlensequenz eine weitere Ziffer hinzugefügt wird, wird sie die nächste Bit-Stufe erreichen und die Potenz wächst um das Doppelte.

Wenn Sie sich nun auf unser aktuelles Problem beziehen, haben wir es mit einer 4-Bit-Stufe zu tun. Da jede Variable durch ein Bit repräsentiert werden kann, würde sich diese Stufe hervorragend eignen.{PSP}Die vier Variablen lassen sich in eine einzige Variable vereinen.

$auswahl = 1 // 0001; (extraHD)
$auswahl = 2 // 0010; (netzkarte)
$auswahl = 4 // 0100; (brenner)
$auswahl = 8 // 1000; (tvkarte)

Natürlich können Sie auch Komponenten miteinander kombinieren:

$auswahl = 5 // 0101; (extraHD und brenner)
$auswahl = 6 // 0110; (netzkarte und brenner)
$auswahl = 10 // 1010; (netzkarte und tvkarte)
$auswahl = 15 // 1111; (alle Komponenten)

Wie Sie sehen, ist die Zusammensetzung individuell zu bestimmen, ohne Probleme lassen sich diese Kombinationen in Form von Zahlen sichern. Das binäre System dahinter sorgt für die korrekte Zuordnung.

Wie können Sie nun die Komponenten hinzufügen, d. h., wie ereichen Sie es, den Brenner oder die TV-Karte der Variablen $auswahl zu übergeben, ohne die davor ausgewählte Komponente zu löschen?

Ein Beispiel

$auswahl = 0; // Rechner ohne zusätzliche Komponenten

Beim Hinzufügen von Komponenten können die einzelnen Komponenten gezielt bestimmt werden:

$auswahl += 2; // 0010 Rechner erhält eine Netzwerkkarte
$auswahl += 1; // 0011 Rechner erhält eine zusätzliche HD
$auswahl += 4; // 0111 Rechner erhält DVD-Brenner
$auswahl += 8; // 1111 Rechner erhält TV-Karte

Der Rechner ist voll aufgerüstet!

Der Vorteil besteht nun darin, dass man natürlich auch Komponenten entfernen kann.

$auswahl -= 4; // 1011 DVD-Brenner wird entfernt
$auswahl -= 2; // 1001 Netzwerkkarte wird entfernt

Der Rechner enthält lediglich eine extraHD und eine TV-Karte!

Nun sollten Sie sich die praktische Umsetzung betrachten, denn, um in PHP bitweise zu programmieren, kommen Sie um die Bitwise-Operatoren nicht herum.{PSP}Beispiel
<?
// Alle Komponenten ausgewählt (kompletter Rechner)
$extraHD = (1<<0); // 1 Bit: 0 (false), 1 (true)
$netzkarte = (1<<1); // 2 Bit: 0 (false), 2 (true)
$brenner = (1<<2); // 3 Bit: 0 (false), 4 (true)
$tvkarte = (1<<3); // 4 Bit: 0 (false), 8 (true)

// Die Komponenten in die Auswahl ablegen (Ergebnis 15)
$auswahl = $extraHD | $netzkarte | $brenner | $tvkarte;

// Hier nun eine Funktion, die den Preis berechnet
function berechne($auswahl) {
  $preis = 0;
  // Wenn das erste Bit gesetzt wurde, 200 Euro
  if ($auswahl & 1) {
    echo "+ Extra HD";
    $preis += 200;
  }
  // Wenn das zweite Bit gesetzt wurde, 150 Euro
  if ($auswahl & 2) {
    echo "+ Netzwerkkarte";
    $preis += 150;
  }
  // Wenn das dritte Bit gesetzt wurde, 450 Euro
  if ($auswahl & 4) {
    echo "+ DVD Brenner";
    $preis += 450;
  }
  // Wenn das vierte Bit gesetzt wurde, 100 Euro
  if ($auswahl & 8) {
    echo "+ TV-Karte";
    $preis += 100;
  }
  return $preis;
}

// Nun testen Sie die Umsetzung
echo berechne($auswahl);

/*
Ausgabe:
+ Extra HD
+ Netzwerkkarte
+ DVD Brenner
+ TV-Karte
900
*/

// Lediglich extraHD und tvkarte ausgewählt
$extraHD = (1<<0); // 1 Bit: 0 (false), 1 (true)
$netzkarte = (0<<1); // 2 Bit: 0 (false), 2 (true)
$brenner = (0<<2); // 3 Bit: 0 (false), 4 (true)
$tvkarte = (1<<3); // 4 Bit: 0 (false), 8 (true)

// Die Komponenten in die Auswahl ablegen (Ergebnis 9)
$auswahl = $extraHD | $netzkarte | $brenner | $tvkarte;

// Nun testen Sie die Umsetzung
echo berechne($auswahl);

/*
Ausgabe:
+ Extra HD
+ TV-Karte
300
*/

?>

Ich hoffe, Ihnen mit diesem Fallbeispiel einen Einblick in die Arbeit der Bitwise-Operatoren verschafft zu haben. Sie müssen natürlich selbst entscheiden, wie weit Sie diese in Ihre Anwendungen einbinden wollen.


Auflistung der bitweisen Operatoren

OperatorBezeichnungBedeutung
&And/UND$a & $b – Bits, die in $a und $b gesetzt sind werden gesetzt.
|Or/ODER$a | $b – Bits, die in $a oder $b gesetzt sind werden gesetzt.
^Xor/Entweder ODER$a ^ $b – Bits, die entweder in $a oder $b gesetzt sind, werden gesetzt, aber nicht in beiden.
~Not/Nicht~ $a – Die Bits, die in $a nicht gesetzt sind, werden gesetzt, und umgekehrt.
<<Shift left/Nach link verschieben$a << $b – Verschiebung der Bits von $a um $b Stellen nach links (jede Stelle entspricht einer Multiplikation mit zwei).
>>Shift right/Nach rechts verschieben$a >> $b – Verschiebt die Bits von $a um $b Stellen nach rechts (jede Stelle entspricht einer Division durch zwei).