Tobias22: Eine Frage zum Bitmuster

Hallo Forum,

ich versuche gerade eine Aufgabe (C-Programmierung) zu lösen, wo man u.a. einen Code erklären soll.

Mir ist klar, dass es sich beim Gesamt-Code um Bitmuster und Schiebeoperatoren handelt. Man gibt eine Zahl ein und kriegt bei der Ausgabe eine 32-stellige Hexadezimale Zahl.

Die folgende Zeilen verstehe ich aber nicht ganz:

unsigned int mask = 01 << 31;
Recherche: "01 << 31" soll die Bits um n Stellen nach links schieben und rechts Nullen auffüllen.

while (i>=0) {
if ((z&mask) !=0)
Recherche: "(z&mask)" soll UND-Operation simultan auf jedes Bit anwenden und ein neues Bitmuster als Wert liefern.

mask >>= 1;}
Recherche: "mask >>= 1" soll eine Zuweisung nach Rechtsverschiebung sein.

Ich kann leider trotzdem nicht nachvollziehen, was das alles bedeutet und wie das Ganze funktioniert.

Könnte mir das jemand erklären?

Tobias

P.S. Ich suche keine fertige Lösung, sondern möchte einfach das Prinzip zu verstehen.

  1. Hallo,

    unsigned int mask = 01 << 31;
    Recherche: "01 << 31" soll die Bits um n Stellen nach links schieben und rechts Nullen auffüllen.

    in diesem Beispiel: Der Wert 1 = 0x00000001, in dem nur das Bit 0 gesetzt ist, wird um 31 Bitpositionen nach links verschoben, so dass am Ende das Bit 31 gesetzt ist und sonst keins. Das ist mathematisch äquivalent zu 2³¹, da das Linksschieben um eine Bitposition der Multiplikation mit 2 entspricht (solange kein Überlauf auftritt).

    while (i>=0) {
    if ((z&mask) !=0)
    Recherche: "(z&mask)" soll UND-Operation simultan auf jedes Bit anwenden und ein neues Bitmuster als Wert liefern.

    Genau. Also alle Bits, die in z UND in mask gesetzt sind, bleiben auch im Ergebnis gesetzt; alle anderen werden zu 0. Übrigens ist der Ausdruck im if-Statement unnötig kompliziert; if () wertet einen Ausdruck ohnehin auf "ungleich Null" aus, so dass der Vergleich keinen besondern Sinn mehr ergibt. Er schadet nicht, aber ein einfaches if (z&mask) tut dasselbe und ist meiner Ansicht nach leichter zu lesen und zu begreifen.

    mask >>= 1;}
    Recherche: "mask >>= 1" soll eine Zuweisung nach Rechtsverschiebung sein.

    Ja. Schiebe das Bitmuster in mask um eine Position nach rechts und schreibe es nach mask zurück.

    Ich kann leider trotzdem nicht nachvollziehen, was das alles bedeutet und wie das Ganze funktioniert.
    Könnte mir das jemand erklären?

    Der Code ist unvollständig. Beispielsweise vermisse ich eine Operation auf i in der while-Schleife, denn der Wert von i muss irgendwo verändert werden, damit die Schleifenbedingung irgendwann mal nicht mehr erfüllt ist. Aber man kann ahnen, dass ein Zahlenwert z von "oben" her, also vom höchstwertigen Bit beginnend, Schritt für Schritt untersucht werden und vermutlich das höchste gesetzte Bit gefunden werden soll.

    So long,
     Martin

    --
    Frauen sind wie Elektrizität: Fasst man sie an, kriegt man eine gewischt.
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    1. Hi Martin,

      erstmal vielen Dank für die ausführliche Antwort!

      Ich habe den Eindruck, dass mir einfach Basisinformation fehlt, was überhaupt Bitmuster ist und ich das deswegen nicht verstehe.

      in diesem Beispiel: Der Wert 1 = 0x00000001, in dem nur das Bit 0 gesetzt ist, wird um 31 Bitpositionen nach links verschoben, so dass am Ende das Bit 31 gesetzt ist und sonst keins.

      Rein intuitiv wird der Wert für mich nach rechts verschoben.
      Was ich meine: wir haben den Wert n=1 => 0000.0000.0000.0000.0000.0000.0000.0001

      Er schadet nicht, aber ein einfaches if (z&mask) tut dasselbe und ist meiner Ansicht nach leichter zu lesen und zu begreifen.

      Gut zu wissen!

      Der Code ist unvollständig. Beispielsweise vermisse ich eine Operation auf i in der while-Schleife, denn der Wert von i muss irgendwo verändert werden, damit die Schleifenbedingung irgendwann mal nicht mehr erfüllt ist.

      Der Code war natürlich unvollständig. Hier ist der vollständige:

      void untprog1(int z)
      {
          unsigned int mask = 01 << 31;
          int i = 31;
          while (i>=0)
          {
              if ((z&mask)!=0)
                  printf("1");
              else
                  printf("0");
              if((i%8==0) && mask!=1)
                  printf(".");
              mask >>= 1;
              i--;
          }

      Gruß Tobias

      1. Om nah hoo pez nyeetz, Tobias22!

        Der Code war natürlich unvollständig. Hier ist der vollständige:

        den man auch als solchen auszeichnen sollte.

        void untprog1(int z)  
        {  
            unsigned int mask = 01 << 31;  
            int i = 31;  
            while (i >= 0)  
            {  
                if ((z&mask) != 0)  
                    printf("1");  
                else  
                    printf("0");  
                if((i%8 == 0) && mask != 1)  
                    printf(".");  
                mask >>= 1;  
                i--;  
            }  
        }
        

        Matthias

        --
        Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Tau und Taucher.

        1. Om nah hoo pez nyeetz, Tobias22!

          Der Code war natürlich unvollständig. Hier ist der vollständige:

          den man auch als solchen auszeichnen sollte.

          void untprog1(int z)

          {
              unsigned int mask = 01 << 31;
              int i = 31;
              while (i >= 0)
              {
                  if ((z&mask) != 0)
                      printf("1");
                  else
                      printf("0");
                  if((i%8 == 0) && mask != 1)
                      printf(".");
                  mask >>= 1;
                  i--;
              }
          }

          
          >   
          > Matthias  
            
            
          Danke, weiß ich für den nächsten Mal Bescheid!  
          Tobias
          
      2. Rein intuitiv wird der Wert für mich nach rechts verschoben.

        Mit einem Linkspfeil nach rechts schieben?

        Mask ist erst
        100000000000000000000000000000000
        dann
        010000000000000000000000000000000
        dann
        001000000000000000000000000000000
        usw.

        Das wird dann über die Zahl z gelegt die du in diese Funktion rein gibst.
        In mask ist immer nur ein Bit nicht 0. z & mask ist also nicht null wenn... ?
        Dann wird 1 ausgegeben. Sonst 0.
        Gib mal 1, 2, 3.... in diese Funktion rein und schau was dabei raus kommt. Dann kommst du schnell drauf was da passiert. Wär fast schon gemein dir diesen Aha Effekt zu versauen :-)

        Übrigens

        und kriegt bei der Ausgabe eine 32-stellige Hexadezimale Zahl.

        Nein man kriegt eine binäre Zahl.

        1. Hi,

          ich les hier grad rein und kapier es ebenso wenig.

          Mask ist erst
          100000000000000000000000000000000
          dann
          010000000000000000000000000000000
          dann
          001000000000000000000000000000000
          usw.

          Das wird dann über die Zahl z gelegt die du in diese Funktion rein gibst.

          Für mich sieht es so aus, als wäre die Schleife wie folgt, wenn ich z=1 eingäbe:

          Erster Durchlauf:
          mask: 10000000000000000000000000000000
          z   : 00000000000000000000000000000001
          --------------------------------------
          Das müßte doch schon in Durchlauf 1 alles andere als 0 ergeben?

          Ich könnte noch nachvollziehen, wenn nach 32 Durchläufen

          11111111111111111111111111111110 herauskäme, aber es kommt ja das genaue Gegenteil raus.

          Wo ist denn da _mein_Denkfehler? :-/

          Tim

          In mask ist immer nur ein Bit nicht 0. z & mask ist also nicht null wenn... ?
          Dann wird 1 ausgegeben. Sonst 0.
          Gib mal 1, 2, 3.... in diese Funktion rein und schau was dabei raus kommt. Dann kommst du schnell drauf was da passiert. Wär fast schon gemein dir diesen Aha Effekt zu versauen :-)

          Übrigens

          und kriegt bei der Ausgabe eine 32-stellige Hexadezimale Zahl.
          Nein man kriegt eine binäre Zahl.

          1. Das müßte doch schon in Durchlauf 1 alles andere als 0 ergeben?

            Warum? Was würdest du als Ergebnis erwarten?

            Wo ist denn da _mein_Denkfehler? :-/

            Vielleicht weil du von der ODER Funktion ausgehst statt von UND?
            Der Begriff UND hat nichts mit zusammenzählen zu tun.

            Ich könnte noch nachvollziehen, wenn nach 32 Durchläufen
            11111111111111111111111111111110 herauskäme

            Nochmal warum? Wenn du nur ein Bit gesetzt hast und dieses Bit hin und her schiebst, dann bleibt genau ein Bit in der Zahl übrig. Nur an einer anderen Stelle.

            1. Hi,

              Wo ist denn da _mein_Denkfehler? :-/
              Vielleicht weil du von der ODER Funktion ausgehst statt von UND?
              Der Begriff UND hat nichts mit zusammenzählen zu tun.

              Ok. Dann war _das_ mein Denkfehler.

              Tim

  2. hi,

    evntl. hilft Dir dieser Artikel weiter.

    MfG

    1. Hi hotti,

      evntl. hilft Dir dieser Artikel weiter.

      Danke schön! Habe endlich alles verstanden!

      Tobias