Bitweise setzen
undso
- datenbank
Hi, mal wieder ich.
Um Spalten zu sparen, habe ich verschiedene Zustände in nur eine Spalte in der DB (SQL) gespeichert.
Bsp. Spalte="Erlaubnis"
Das erste Bit ob man ein Newsletter will. Das zweite Bit, ob man Sounds ausgeschaltet haben will usw.
Ich könnte zwar jetzt mit Zahlen arbeiten. Addieren oder Subtrahieren
Für jede Bitstelle jeweils:
1 2 4 8 16 usw.
Hier kann man aber schnell faken, bei nem kleinen Fehler ist das ganze fast Pfutsch.
Bzw. manchmal muss ich bevor man etwas speichern will, zusätzlich das Bit auslesen, damit man nicht doppelt die Zahl addiert, falls das Bit schon gesetzt ist.
Deshalb meine Frage, da ich nicht fündig wurde.
Kann man eigentlich ein bestimmtes Bit setzen oder nicht setzen, egal was für ein Urzustand das ganze hat?
update Tabelle set Erlaubnis=???
Grüße
echo $begrüßung;
Um Spalten zu sparen, habe ich verschiedene Zustände in nur eine Spalte in der DB (SQL) gespeichert.
MySQL böte dafür den Typ SET an.
Kann man eigentlich ein bestimmtes Bit setzen oder nicht setzen, egal was für ein Urzustand das ganze hat?
Bit setzen geht mit einem Bitoperatoren-OR, löschen mit AND NOT
xxxxxxxx
or 00010000
xxx1xxxx
xxxxxxxx
and 11101111 das ist die negierte Form von 00010000
xxx0xxxx
echo "$verabschiedung $name";
Hi,
wenn ich das nun vorliegen habe: 101001 und ich das dritte Bit löschen will, mache ich:
update Tabelle set Erlaubnis=Erlaubnis>>3 & 0;
das dritte Bit setzen so:
update Tabelle set Erlaubnis=Erlaubnis>>3 | 0;
War das jetzt überhaupt richtig so. Muss mal die Doku nochmal durchgehen. Oder mache ich das so wie du mit den x'en?
So könnte ich dann mehrere bit gleichzeitig setzen:
Bsp. Bit 2 und 3 löschen
update Tabelle set Erlaubnis=Erlaubnis & x00xxx;
setzen:
update Tabelle set Erlaubnis=Erlaubnis | x11xxx;
Könnte man in einer Query zweimal das gleiche Feld updaten?
Sprich, Bsp. ein bestimmtes Bit setzen und ein anderes löschen?
Grüße
echo $begrüßung;
wenn ich das nun vorliegen habe: 101001 und ich das dritte Bit löschen will, mache ich:
Bits zählt man im Allgemeinen von rechts, weil die Wertigkeit nach links zu größer wird. (Rechts? Links? Unklar? Das rechte Bit muss vorhanden sein, die links stehenden immer nur wenn die rechten Bits nicht mehr ausreichen, um einen Wert darzustellen.)
Um das x. Bit zu erhalten, kann man das 1. Bit setzen (also das niederwertigste) und es x -1 Mal nach links schieben. Dieser Wert bildet die Maske, die gegebenenfalls noch bitweise invertiert verden muss.
update Tabelle set Erlaubnis=Erlaubnis>>3 & 0;
das dritte Bit setzen so:
update Tabelle set Erlaubnis=Erlaubnis>>3 | 0;
Das sieht nicht richtig aus.
So könnte ich dann mehrere bit gleichzeitig setzen:
Bsp. Bit 2 und 3 löschen
update Tabelle set Erlaubnis=Erlaubnis & x00xxx;
setzen:
update Tabelle set Erlaubnis=Erlaubnis | x11xxx;
Das sieht schon besser aus, abgesehen von der Zählweise. Aber statt der x musst du im ersten Fall 1 nehmen und im zweiten 0.
Könnte man in einer Query zweimal das gleiche Feld updaten?
Nein, aber ...
Sprich, Bsp. ein bestimmtes Bit setzen und ein anderes löschen?
... du kannst mehrere Rechenoperationen nacheinander ausführen. x = x | y & z
echo "$verabschiedung $name";
Hi dedlfix,
Das sieht schon besser aus, abgesehen von der Zählweise. Aber statt der x musst du im ersten Fall 1 nehmen und im zweiten 0.
Oki, jetzt habe ich es gecheckt:
Bsp. Spalte: Erlaubnis 101001
Ich lösche das zweite und dritte Bit mit &:
101001
100111 &
-----------
100001
Ich setze das zweite und dritte Bit mit |
101001
011000 |
-----------
111001
... du kannst mehrere Rechenoperationen nacheinander ausführen. x = x | y & z
Oki, das muss ich mal probiere, wie dir Query dann aussieht:
update Tabelle set Erlaubnis= Erlaubnis&100111 | Erlaubnis|011000 ??
Was mich nun interessiert:
Wenn die Spalte "Erlaubnis" 8 Bits hat: 10110101
Ich dies aber im Vorhinein nicht weiß unr nur das zweite und dritte Bit setzen will.
10110101
011 |
--------------
111.....
Was passiert mit den restlichen Bits?
Grüße
echo $begrüßung;
... du kannst mehrere Rechenoperationen nacheinander ausführen. x = x | y & z
Oki, das muss ich mal probiere, wie dir Query dann aussieht:update Tabelle set Erlaubnis= Erlaubnis&100111 | Erlaubnis|011000 ??
Das Erlaubnis brauchst du nur einmal (rechts vom =)
101001
100111 &
000010 |
-----------
100011
Was mich nun interessiert:
Wenn die Spalte "Erlaubnis" 8 Bits hat: 10110101
Ich dies aber im Vorhinein nicht weiß unr nur das zweite und dritte Bit setzen will.
Ich sagte doch, du sollst von rechts zählen. Das ist die übliche Richtung, in der Zahlen um weitere Ziffern wachsen. Und "rechtsbündig" werden auch "unterschiedlich lange" Zahlen miteinander verknotet.
10110101
011 111..... Was passiert mit den restlichen Bits?
Die werden als 0 angesehen, aber die linken, nicht die rechten fehlenden Stellen.
10110101
011 |
--------------
10110111
echo "$verabschiedung $name";
Hi,
Das Erlaubnis brauchst du nur einmal (rechts vom =)
Ach ja, oki stimmt. Sorry, die Tage brauche ich irgendwie länger, bis ich das kapiere ;) Habs aber verstanden.
101001
100111 &
000010 100011
Ich sagte doch, du sollst von rechts zählen. Das ist die übliche Richtung, in der Zahlen um weitere Ziffern wachsen. Und "rechtsbündig" werden auch "unterschiedlich lange" Zahlen miteinander verknotet.
10110101
011 111..... Was passiert mit den restlichen Bits? Die werden als 0 angesehen, aber die linken, nicht die rechten fehlenden Stellen.
10110101
011 |
--------------
10110111
Oki, ich hab die Rechnung dann falschbündig geschrieben. Einfach nur andersrum
Ich hatte mit dem niederwertigsten Bit links angefangen ;)
Vielen Dank dann für Deine Bemühungen.
Grüße
echo $begrüßung;
Oki, ich hab die Rechnung dann falschbündig geschrieben. Einfach nur andersrum
Ich hatte mit dem niederwertigsten Bit links angefangen ;)
Nein, das ist immer noch falsch. Das niederwertigste Bit steht recht und das höchstwertige links. Genauso wie bei Zahlen im Dezimalsystem. Je weiter links eine Ziffer steht, desto höherwertiger ist die Stelle.
Betrachte die Bitoperationen als gleichwertig zu Addition und Subtraktion. Auf dem Papier werden die Zahlen rechtsbündig notiert und dann ausgerechnet. Im Computer ist die Stellenanzahl in 8er-Schritten vorgegeben. Alles was kürzer ist, muss nach links hin mit Nullen aufgefüllt werden. Und das hat keine Auswirkungen auf den Wert einer Zahl hat. 00543 bleibt 543, 54300 ist was anderes.
echo "$verabschiedung $name";
Hi,
Nein, das ist immer noch falsch. Das niederwertigste Bit steht recht und das höchstwertige links. Genauso wie bei Zahlen im Dezimalsystem. Je weiter links eine Ziffer steht, desto höherwertiger ist die Stelle.
Betrachte die Bitoperationen als gleichwertig zu Addition und Subtraktion. Auf dem Papier werden die Zahlen rechtsbündig notiert und dann ausgerechnet. Im Computer ist die Stellenanzahl in 8er-Schritten vorgegeben. Alles was kürzer ist, muss nach links hin mit Nullen aufgefüllt werden. Und das hat keine Auswirkungen auf den Wert einer Zahl hat. 00543 bleibt 543, 54300 ist was anderes.
Ja genau, habs wiedermal falsch beschrieben, ich weiß aber was du meinst ;)
Also, nochmals danke. als nächstes muss ich mir das ganze Datenbankdesign durch den Kopf gehen lassen und alles neu planen, bevor ich das ganze von Grundauf falsch angehe. Aber das mit den Bits sitzt schon denke ich.
Grüße