Spaß mit Bits



  • #include <iostream>
    #include <cassert>
    
    #define MASK_BIT1 (1 << 0 | 1 << 1 | 1 << 2 | 1 << 3 | 1 << 4)
    #define MASK_BIT2 (1 << 0 | 1 << 1 | 1 << 2)
    
    int get_bits1(unsigned char c)
    {
    	// Start: 11111111
    
    		     // => 76543210
    	c >>= 3; // => 00011111
    
    	return c & MASK_BIT1;
    }
    
    int get_bits2(unsigned char c)
    {
    	// Start: 11111111
    
    			 // => 76543210
    	c >>= 5; // => 00000111
    
    	return c & MASK_BIT2;
    }
    
    void set_bits1(unsigned char& c, unsigned char val)
    {
    	c = c | val << 3;
    }
    
    void set_bits2(unsigned char& c, unsigned char val)
    {
    	// Nehme ich folgenden Teil mit rein, dann ist der andere Wert, welcher mit set_bits1 festgelegt wurde plötzlich falsch
    
    	//c = c | val << 5;
    }
    
    int main()
    {
    	unsigned int total = 0;
    	unsigned int wrong = 0;
    
    	for (unsigned int i = 0; i <= 31; ++i)
    	{
    		for (unsigned int j = 0; j <= 7; ++j)
    		{
    			unsigned char c = 0;
    
    			set_bits1(c, i);
    			set_bits2(c, j);
    
    			++total;
    
    			if (get_bits1(c) != i || get_bits2(c) != j)
    			{
    				++wrong;
    
    				//continue;
    			}
    
    			std::cout << i << " = " << get_bits1(c) << std::endl;
    			std::cout << j << " = " << get_bits2(c) << "\n" << std::endl;
    		}
    	}
    
    	std::cout << total - wrong << " of " << total << std::endl;
    
    	return 0;
    }
    

    Der Aufruf von set_bits2 macht den mit set_bits1 gesetzten Wert zu nichte.



  • #include <iostream>
    
    int get_bits1(unsigned char c) // Bit 0 bis 4
    {
        return c&0x1f;
    }
    
    int get_bits2(unsigned char c)
    {
        return (c&0x60)>>5;
    }
    
    void set_bits1(unsigned char& c, unsigned char val) // Bit 5 und 6
    
    {
    	c &= 0xe0;
    	c |= val;
    }
    
    void set_bits2(unsigned char& c, unsigned char val)// val 0 bis 3 !
    {
        c &= 0xf9;
    	c |= val<<5;
    }
    
    int main()
    {
        unsigned char c;
    
        set_bits1(c, 24);
        set_bits2(c, 3);
    
        std::cout << get_bits1(c) << std::endl;
        std::cout << get_bits2(c) << std::endl;
    
        return 0;
    }
    

    😉



  • Ändert man aber z.B. set_bits1(c, 24); auf set_bits1(c, 12); dann passt es wieder nicht... Und genau hier liegt ständig mein Problem. Es ist nie allgemeingültig und funktioniert nicht immer zuverlässig.





  • Das hat jetzt aber mit deinem Eingangspost wenig zu tun:

    Zugreifen möchte ich im Byte auf folgende Bits:
    Bit 1-5 (Wertbereich 0-32)
    Bit 6-7 (Wertbereich 0-4)
    Bit 8 (Wertbereich 0-1)

    einGasts Korrektur unbenommen.

    get_bits1() gibt Dir die fünf obersten Bits von c.
    get_bits2() gibt Dir die drei obersten Bits von c.
    Das überschneidet sich.

    Genauso überschreiben set_bits1() u. set_bits2() sich gegenseitig

    Du wolltest doch a) die ersten fünf, b) die nächsten zwei und c) das letzte eine Bit.
    Also das, was ich vorhin anbot, oder funktionierte das nicht?



  • @einGast:

    in Deiner set_bits2() meist Du - glaube ich:

    &=0x9F;
    

    Oder verrenne ich mich hier?



  • ghjghj schrieb:

    Ändert man aber z.B. set_bits1(c, 24); auf set_bits1(c, 12); dann passt es wieder nicht... Und genau hier liegt ständig mein Problem. Es ist nie allgemeingültig und funktioniert nicht immer zuverlässig.

    Da ist ein Zahlendreher drinn 0xf9, es muss 0x9f heißen, also

    #include <iostream>
    
    int get_bits1(unsigned char c) // Bit 0 bis 4
    {
        return c&0x1f;
    }
    
    int get_bits2(unsigned char c)
    {
        return (c&0x60)>>5;    // Bit 5 und 6
    
    }
    
    void set_bits1(unsigned char& c, unsigned char val) // Bit 0 bis 4
    
    {
    	c &= 0xe0;
    	c |= val;
    }
    
    void set_bits2(unsigned char& c, unsigned char val)// val 0 bis 3 !
    {
        c &= 0x9f;
    	c |= val<<5;
    }
    
    int main()
    {
        unsigned char c;
    
        set_bits1(c, 24);
        set_bits2(c, 2);
    
        std::cout << get_bits1(c) << std::endl;
        std::cout << get_bits2(c) << std::endl;
    
        return 0;
    }
    

    Probier es!



  • Caligulaminus schrieb:

    @einGast:

    in Deiner set_bits2() meist Du - glaube ich:

    &=0x9F;
    

    Oder verrenne ich mich hier?

    Du hast Recht, hab den Wert vom Hexrechner verdreht übernommen. 🙂



  • Neues vom Hexer 🤡



  • ghjghj schrieb:

    314159265358979 schrieb:

    Es soll auch Systeme geben, die nicht 8 Bit haben 😃

    Ja, das ist klar. Trotzdem sollte man es mit Portabilität nicht übetreiben. Mein Programm hat auf einem Toaster schließlich nichts zu suchen.

    Darüberhinaus behaupte ich mal, daß alle Toaster, die derzeit verkauft werden, falls die Mikroprozessoren benutzen, auch 8-Bit-Bytes haben.



  • Overkill! Wozu 8 Bit wenn maximal 4 Toasts reinpassen?

    Edit: Mein Fehler. Natürlich, um den genügenden Bräunungszustand auf beiden Seiten aller 4 Toasts darstellen zu können.



  • Für jede Seite des Toasts ein Bit.



  • Da war ich zum Glück für jedes Bit im Byte eine Sekunde schneller 😉



  • 😞



  • Bitte ein Bit *scnr*



  • Ja, mir ist auch nicht klar, warum die noch keinen Bitburger Eightpack an den Markt gebracht haben.
    Gut wäre auch einer, der sich in zwei Nibbles aufteilen ließe.


Anmelden zum Antworten