Letzten bits eines bytes ersetzen



  • Hallo Leute,

    ich hoffe, ihr könnt mir helfen. Aktuell bleibe ich an einem Bit-Operator problem hängen.

    Folgendes:
    Ich habe eine Zahl als binärzahl, welche über 3 bytes geht:

    byte src = 000000001111111100000000;
    und 3 bits: a = 1; b = 0; c = 1;
    

    Jede dieser bites möchte ich ans ende eines bytes setzen:

    {byte} src = 0000000[b]a[/b]1111111[b]b[/b]0000000[b]c[/b]; // ja, noch falscher typ, ich weiß.
    // also:
    byte src = 0000000[b]1[/b]1111111[b]0[/b]0000000[b]1[/b];
    

    soll daraus werden.
    Kann mir da jemand unter die Arme greifen?



  • Also 3 Byte große Datentpen gibt es afaik nicht, da würde ich vermutlich ein Array aus drei char verwenden. Und dann brauchst du für's Setzen und Rücksetzen unterschiedliche Anweisungen:

    //Bit auf 1 setzen:
    x[i] |= 1;
    //Bit auf 0 setzen:
    x[i] &= ~1;
    


  • Und wie sähe das wohl letzendlich aus?
    Müsste da nicht sowas wie hier rauskommen?
    [cpp]
    src = 000000001111111100000000;
    ebits = ((bitsa & 4) << 14) | ((bitsb & 2) << 7) | (bitsc & 1);
    ebytes = src | ebits;



  • Vermutlich ist es nicht ganz si einfach wie du dir das denkst, weil du für jeden deiner Vorgabewerte eine Fallunterscheidung benötigst. Aber vorher mußt du dir klar werden, welche Datentyp du eigentlich verwenden willst (int oder long sind üblicherweise 4 Byte groß, exakt drei Byte bekommst du wohl nur mit char[3]).



  • void setBit(char *data, int pos, char val)
    {
      int s = pos / 8;
      if (val % 2)
        data[s] |= (1 << (pos - s * 8));
      else
        data[s] &= ~(1 << (pos - s * 8));
    }
    
    int main()
    {
      char x[3] = {0};
      setBit(x, 12, 1);
    }
    


  • CStoll schrieb:

    //Bit auf 1 setzen:
    x[i] |= 1;
    //Bit auf 0 setzen:
    x[i] &= ~1;
    

    Inspiriert durch diesen Codeschnipsel, habe ich mal ein wenig gespielt:

    #include<stdlib.h>
    #include <stdio.h>
    //
    
    int main()
    {   
      char a = 'a'; // Binär "0110 0001" , Dec. "97"
      printf ("Wert ursprünglich: %d\n", a);
      // Löscht das letzte Bit
      a &= ~1; // Bitweises AND mit NOT 1
      printf ("Bit gelöscht: %d\n", a);
      // Setzt das Bit wieder
      a |= 1; // Bitweises OR 1
      printf ("Bit wieder gesetzt: %d\n", a);
      // Löscht das Bit wieder
      a ^= 1; // Banales bitweises XOR
      printf ("Bit wieder gelöscht: %d\n", a);
      // Einerkomplement
      a = ~a;
      printf ("Einerkomplement ~a: %d\n", a);
    	return 0;
    }
    

    Es ist über 25 Jahre her, dass ich mich mit boolesche Algebra rumschlagen musste....

    AND mit NOT ist doch gleich NAND??
    NAND wäre dann doch XOR?? Aber irgendwie passt das nicht... Was genau macht

    a &= ~1
    

    😕

    Aber heute ist Samstag - ich stehe wahrscheinlich auf dem Schlauch...



  • Ist nicht schwer:

    00100000  ; Beispiel 2[h]6[/h]: 64
      | 00000001  ; 1
        --------
        00100001  ; 65
    
    ~1: 11111110
      & 00100001  ; 65
        --------
        00100001  ; 64
    

    Das heißst, es tut das, was es soll: Das LSB wird erst gesetzt und im zweiten Schritt auf jeden Fall gelöscht (0 & <irgendwas> ist immer 0).



  • George Boole cool schrieb:

    AND mit NOT ist doch gleich NAND??

    Das kommt ganz auf die Reihenfolge an, in der du die Operatoren anwendest.

    NAND wäre dann doch XOR??

    Nein, das ist etwas völlig anderes. (aber dazu hilft ein Blick in ein Informatik-Buch ;))

    Aber irgendwie passt das nicht... Was genau macht

    a &= ~1
    

    😕

    ~1 ist bitweise Negation (invertiert alle Bits des Wertes 1), das wird dann per AND mit deiner Eingabe verknüpft.



  • Also bedeudet

    a &= ~1
    

    aufgelöst das:

    #include<stdlib.h>
    #include <stdio.h>
    //
    
    int main()
    {   
      char a = 'a', // Binär "0110 0001" , Dec. "97"
           b=a;
      printf ("Wert ursprünglich: %d\n", a);
      // Löscht das letzte Bit
      a = ~1; 
      printf ("Einerkomplement ~a: %d\n", a);
      a &= b;
      printf ("Bit gelöscht: %d\n", a);
    	return 0;
    }
    

    😕

    CStoll schrieb:

    NAND wäre dann doch XOR??

    Nein, das ist etwas völlig anderes. (aber dazu hilft ein Blick in ein Informatik-Buch ;))

    Eben, daher die Frage 😉



  • Nein,
    das Einerkomplement von a ist ~a (nicht ~1)

    a &= ~1 oder a &= 0xfffffffe oder a = a & 0xfffffffe



  • DirkB schrieb:

    Nein,
    das Einerkomplement von a ist ~a (nicht ~1)

    a &= ~1 oder a &= 0xfffffffe oder a = a & 0xfffffffe

    Besten dank - habs kapiert...
    Aber warum nicht gleich

    a &= -2;
    

    Mein Code oben ist schon richtig... der Text im printf ist falsch...

    Nochmals besten Dank und schönes WE



  • George Boole jun. schrieb:

    Aber warum nicht gleich

    a &= -2;
    

    Weil nicht vorgeschrieben ist, daß int mit Zweierkomplement rechnet. Merke: Wenn du mit einzelnen Bits arbeiten willst, nimm Bit-Operatoren.


Anmelden zum Antworten