Schöne Aufgabe
-
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 extraCHAR_BIT
auslimits.h
-
DirkB schrieb:
Du darfst nicht davon ausgehen, dass ein
char
aus 8 Bit besteht.
Dafür gibt es extraCHAR_BIT
auslimits.h
Aufgabenstellung: "Schreiben Sie einen Code der die Bits eines 8 Bit char umdreht."
-
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:
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 ?
-
Hier noch eine Version, die
1. Als Funktion ausgelegt ist
2. Die Bits der Variable umdrehtvoid reverse(unsigned char *a) { unsigned char tmp=0; for(unsigned int mask=1; mask<=0x80; mask<<=1) { tmp = (tmp << 1) | ((*a & mask) != 0); } *a = tmp; }
Es ist zwar eigentlich sinnfrei, aber zur Übung auch die ASM-Version:
void reverse(unsigned char *a) { __asm{ xor cl,cl ;tmp mov eax,1 ;mask mov ebx,dword ptr [a] ;Adresse a mov edi,edi label1: movzx edx,byte ptr [ebx] test al,dl setne dl add cl,cl ;tmp<<1 add eax,eax ;mask<<1 or cl,dl ;tmp = tmp | ... cmp eax,80h ;mask<=0x80 ? jbe label1 mov byte ptr [ebx],cl ;*a=tmp } }
Da inline ASM bei x64 nicht unterstützt wird, wäre es evtl.
besser das in eine getrennte Datei zu packen.
-
DirkB schrieb:
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
Ich weiss nicht, ieviele Eintraege deine Lookup-Tabelle hat, aber meine haette 16. Die wuerde ich per Hand generieren.