undso: Bitweise setzen

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

  1. 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";

    1. 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

      1. 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";

        1. 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

          1. 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";

            1. 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

              1. 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";

                1. 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