Schöne Aufgabe



  • Keine 5 Sekunden
    Geht doch mit dem Assemblerbefehl ror bzw. rol ganz einfach. Oder hat die Aufgabe einen fiesen haken den ich gerade überseh??



  • floorball schrieb:

    Keine 5 Sekunden
    Geht doch mit dem Assemblerbefehl ror bzw. rol ganz einfach. Oder hat die Aufgabe einen fiesen haken den ich gerade überseh??

    Assembler? Willst du inline Assembler machen ? Wie sieht da der Code aus ? Dachte ja eigentlich an reines C oder C++ 🙂



  • Ich hab ne super Lösung reines C und voll eficent

    #include <stdlib.h>
    #include <stdio.h>
    #include <assert.h>
    #include <limits.h>
    
    struct bits8 {
    	char bit[8];
    };
    
    char bit_to_char(long long from, unsigned int bit_nr)
    {
    	if(from & (1 << bit_nr)) {
    		return '1';
    	}
    	return '0';
    }
    
    long long char_to_bit(char from, unsigned int bit_nr)
    {
    	int bit = 0;
    	if(from == '1')
    		bit = 1;
    	return 0LL | (bit << bit_nr);
    }
    
    struct bits8 char_to_bits8(char this)
    {
    	struct bits8 to;
    	unsigned int i = 0;
    	for(; i < 8; i++) {
    		to.bit[i] = bit_to_char(this, i);
    	}
    	return to;
    }
    
    char bits8_to_char(struct bits8 this)
    {
    	char to = 0;
    	unsigned int i = 0;
    	for(; i < 8; i++) {
    		to |= char_to_bit(this.bit[i], i);
    	}
    	return to;
    }
    
    struct bits8 bits8_reverse(struct bits8 from)
    {
    	struct bits8 to;
    	unsigned int i = 0;
    	for(; i < 8; i++) {
    		to.bit[i] = from.bit[7 - i];
    	}
    	return to;
    }
    
    void print_bits8(struct bits8 this)
    {
    	int i = 0;
    	for(; i < 8; i++) {
    		putchar(this.bit[i]);
    	}
    	putchar('\n');
    }
    
    char reverseBits8(char of)
    {
    	struct bits8 bits = char_to_bits8(of);
    	print_bits8(bits);
    	bits = bits8_reverse(bits);
    	print_bits8(bits);
    	return bits8_to_char(bits);
    }
    
    int main(void)
    {
    	assert(CHAR_BIT == 8);
    	int in;
    	fputs(">", stdout);
    	scanf("%i", &in);
    	printf("%i\n", reverseBits8(in) );
    	return EXIT_SUCCESS;
    }
    


  • Also nachdem ich mir die Aufgabe nochmal durchgelesen habe, habe ich jetzt gemerkt, dass es mit ror bzw. rol nicht funktionieren kann, da man das Byte ja nicht rotieren sondern (wenn ich es jetzt richtig verstanden habe) in der Mitte spiegeln soll.
    Mein Lösungsansatz sähe dazu so aus: (C++ NICHT C blurry meinte ja das C++ auch in Ordnung sei)

    #include <iostream>
    #include <bitset>
    #include <math.h>
    using namespace std;
    
    bitset<8> bits1, bits2;
    
    int main()
    {
    	bits1 =  (char)rand();
    //Hier der eigentliche "spiegelcode"
    	for(int i = 0; i < 8; i++){
    		bits2[7-i] = bits1[i];
    
    	};
    //bis hier
    	cout<<bits1<<endl<<bits2<<endl;
    
    	getchar();
    	return 0;
    };
    


  • Lol sobald man ein array hat gehts schon leichter. Aber probiers mal ohne. sondern mit >> Operator . Ich hab noch keine Lösung. Also mit bitset ist es schon leicht klar.



  • floorball schrieb:

    Also nachdem ich mir die Aufgabe nochmal durchgelesen habe, habe ich jetzt gemerkt, dass es mit ror bzw. rol nicht funktionieren kann, da man das Byte ja nicht rotieren sondern (wenn ich es jetzt richtig verstanden habe) in der Mitte spiegeln soll.

    Aber mit rcr und rcl sollte es einfacher klappen.



  • blurry333 schrieb:

    Lol sobald man ein array hat gehts schon leichter. Aber probiers mal ohne. sondern mit >> Operator . Ich hab noch keine Lösung. Also mit bitset ist es schon leicht klar.

    Lookup table ...



  • knivil schrieb:

    blurry333 schrieb:

    Lol sobald man ein array hat gehts schon leichter. Aber probiers mal ohne. sondern mit >> Operator . Ich hab noch keine Lösung. Also mit bitset ist es schon leicht klar.

    Lookup table ...

    Die man mit einem C-Programm generiert 😃



  • blurry333 schrieb:

    Lol sobald man ein array hat gehts schon leichter. Aber probiers mal ohne. sondern mit >> Operator . Ich hab noch keine Lösung. Also mit bitset ist es schon leicht klar.

    #include <stdio.h>
    
    void println_bin (unsigned char a)
    {
        int i;
        unsigned char mask = 0x80;
        unsigned char b;
        for (i = 0; i<8; ++i)
        {
            b = (a & mask) ? '1' : '0';
            printf ("%c ",b);
            a <<= 1;
        }
        puts("");
    }
    
    int main ( void )
    {
        int i;
        unsigned char a = 0x57;     /* Beispiel: 01010111 => 11101010 */
        unsigned char b = 0;
        unsigned char mask = 0x80;  /* 10000000 */
    
        println_bin (a);            /* Eingabe */
    
        for (i=0; i<8; ++i)
        {
            if (a & 1) b |= mask;
            mask >>= 1;
            a >>= 1;
        }
    
        println_bin (b);            /* Ergebnis */
        return 0;
    }
    

    Etwa 10 Minuten vorrangig für Tipperei. Wer das nicht aus dem Ärmel schütteln kann, kann nicht programmieren.

    Für welchen Compiler willst Du Inline-Assembler?

    viele grüße
    ralph



  • rkhb schrieb:

    ...
        unsigned char mask = 0x80;
    ...
        for (i = 0; i<8; ++i)
    ...
    

    Du darfst nicht davon ausgehen, dass ein char aus 8 Bit besteht.
    Dafür gibt es extra CHAR_BIT aus limits.h



  • DirkB schrieb:

    Du darfst nicht davon ausgehen, dass ein char aus 8 Bit besteht.
    Dafür gibt es extra CHAR_BIT aus limits.h

    Aufgabenstellung: "Schreiben Sie einen Code der die Bits eines 8 Bit char umdreht."



  • @floorball

    Du musst das bitset natürlich wieder in den char zurückschreiben !! So ist die Aufgabe noch nicht erfüllt.



  • Cool also eine Lösung haben wir ja schon mal. Echt klasse. Und Inline Assembler für Visual Studio Compiler *gg* Keine Ahnung wie der dann heisst.



  • blurry333 schrieb:

    @floorball

    Du musst das bitset natürlich wieder in den char zurückschreiben !! So ist die Aufgabe noch nicht erfüllt.

    Laut Aufgabenstellung nicht!

    blurry333 schrieb:

    Schreiben Sie einen Code der die Bits eines 8 Bit char umdreht

    Und das habe ich ganz klar erfüllt, schließlich sind in meinem bitset bits2 die 8 Bits des chars umgedreht



  • ok nach 3 Stunden refactoring habe ich folgende lösung:

    char reverseBits8(char from)
    {
    	char to = 0;
    	int i=0;
    	for(; i < 8; i++) {
    		if(from & (1 << i)) {
    			to |= 1 << (7 - i);
    		}
    	}
    	return to;
    }
    


  • Du sollst die bits des char umdrehen !! Des char !!!



  • blurry333 schrieb:

    Du sollst die bits des char umdrehen !! Des char !!!

    besser?

    char reverseBits8(char from)
    {
    	char table[256];
    	unsigned int ak = 0;
    	for(; ak <= 255; ak++) {
    		table[ak]=0;
    		int i=0;
    		for(; i < 8; i++) {
    			if(ak & (1 << i)) {
    				table[ak] |= 1 << (7 - i);
    			}
    		}
    
    	}
    	return table[(unsigned char)from];
    }
    


  • blurry333 schrieb:

    Cool also eine Lösung haben wir ja schon mal. Echt klasse. Und Inline Assembler für Visual Studio Compiler *gg* Keine Ahnung wie der dann heisst.

    Ich nenne ihn dann immer MSVC (Microsoft Visual C/C++), die Executable heißt "cl.exe". Inline Assembler gibt es nur für die 32-Bit-Version:

    #include <stdio.h>
    
    void println_bin (unsigned char a)
    {
        int i;
        unsigned char mask = 0x80;
        unsigned char b;
        for (i = 0; i<8; ++i)
        {
            b = (a & mask) ? '1' : '0';
            printf ("%c ",b);
            a <<= 1;
        }
        puts("");
    }
    
    int main ( void )
    {
        unsigned char a = 0x57;     /* Beispiel: 01010111 => 11101010 */
        unsigned char b;
    
        println_bin (a);            /* Eingabe */
    
        __asm {
            movzx eax, a
            mov ecx, 8
            L:
            shr al, 1
            rcl ah, 1
            loop L
            mov b, ah
        }
    
        println_bin (b);            /* Ergebnis */
        return 0;
    }
    

    viele grüße
    ralph



  • Ja. Aufgabe gelöst 🙂



  • Eine Frage hätt ich noch. Ich hab hier einen Intel Prozessor. Versteht der den Assembler Code oder muss der noch mal geändert werden ?


Anmelden zum Antworten