Hallo, ich habe eine 16Bit Variable z.B. mit dem Inhalt 0b1100000100000100 ich bräuchte aber die Wertigkeit gerade in die andere Richtung also 0b0010000010000011 gibt es da einen einfachen Weg das umzudrehen? Ich hoffe ich habe mich einigermaßen Verständlich ausgedrückt. Vielen Dank schonmal !
So habe ich einen 12bit-Wert, der in einer 16bit-Variable gespeichert ist, umgedreht. Ist aber quick-and-dirty. // 0b 0000 0001 0000 0100 // wird zu // 0b 0000 0010 0000 1000 // die ersten 4 bits sind immer 0b0000 unsigned short ushort_rev(unsigned short x) { unsigned short val = 0, mask; for(int i=0; i<12; ++i) { mask = x & 0x0FFF; mask = mask << (i+1); val &= ~(1<<i); val |= ((mask & 0x1000) >> 12-i); } return (val); } Blackbird
@Blackbird Vielen Dank das war genau das was ich gesucht habe. Würde mich Interessieren ob es noch eine andere Möglichkeit ohne Schleife gibt.
Man kann das auch über Tabellen machen, entweder 1x 64kWorte oder aufteilen in 2 Bytes und eine 256Byte Tabelle const u8 Tabelle[256] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, .... 0x3f, 0xbf, 0x7f, 0xff}; Val_u16 = ((Tabelle[Old_u16 && 0x00ff] << 8) + (Tabelle[(Old_u16 >> 8) && 0x00ff]);
Martin Schneider wrote: > Man kann das auch über Tabellen machen, > entweder 1x 64kWorte oder aufteilen in 2 Bytes und eine 256Byte Tabelle > > const u8 Tabelle[256] = { 0x00, 0x80, 0x40, 0xc0, > 0x20, 0xa0, 0x60, 0xe0, > .... > 0x3f, 0xbf, 0x7f, 0xff}; > > Val_u16 = ((Tabelle[Old_u16 && 0x00ff] << 8) > + (Tabelle[(Old_u16 >> 8) && 0x00ff]); Nibble-mässig ist wahrscheinlich eine gute Mischung aus Laufzeit und Speicherverbrauch.
int input; int a; int b = 0x0001; int result = 0; for(a = 0x8000;a>0;a/=2) { if (input & a) result |= b; b *= 2; } oder nicht? Sollte so um die 16 Durchläufe brauchen...
1 | $ fortune -m '<<' |
2 | %% (fortunes) |
3 | n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa); |
4 | n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc); |
5 | n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0); |
6 | n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00); |
7 | n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000); |
8 | |
9 | -- C code which reverses the bits in a word. |
Hatten wir schon mal. Bei 8 bits lohnt sich das nicht, da ist die einfache Schleife schneller und kleiner. Bei 16 bits kann sich das schon lohnen.
Ja, so geht das für 32 Bit. Einen Tack schneller gehts noch: bei 16 Bit kann man einmal die Bytes vertauschen und für nen Atmel Proz. kann man einmal 'swap' benutzen, das tauscht die 4Bit Hälften eines Bytes. Cheers Detlef
wie waere es mit val ^ 0b1111111111111111 ( eor 0xffff ) ? gruss horst
>val ^ 0b1111111111111111 ( eor 0xffff ) ?
da kommt das gleiche raus wie bei ~val...
Nur zum Sammeln: Eine Möglichkeit habe ich auch noch. Allerdings als inline-assembler und damit nur auf AVR lauffähig:
1 | #define swapbits(x) asm volatile ( "lsl %1\n\t ror %0 \n\t " \
|
2 | "lsl %1\n\t ror %0 \n\t " \
|
3 | "lsl %1\n\t ror %0 \n\t " \
|
4 | [16 Mal]
|
5 | "lsl %1\n\t ror %0 \n\t " \ |
6 | "lsl %1\n\t ror %0 \n\t " \ |
7 | : "=r" (x): "r" (x)); |
Das braucht exakt 32 Takte.
1 | /***** Kehr die Reihenfolge der Bits um *****/
|
2 | char turn8bit(char val) |
3 | {
|
4 | char i; |
5 | char mirr; |
6 | |
7 | i = 0; |
8 | mirr = 0; |
9 | // Bits umtauschen
|
10 | while(i<8) |
11 | {
|
12 | mirr |= ((val>>i)&0x1)<<(7-i); |
13 | ++i; |
14 | }
|
15 | return mirr; |
16 | }
|
Das ist meine Lösung für PIC mit dem HT Compiler. Das lässt sich auch auf 16 Bit erweitern. Der Vorteil hier, es gibt nur zwei Shiftoperationen. Viel Spaß dabei
Martin schrieb: > Das lässt sich auch > auf 16 Bit erweitern. Der Vorteil hier, es gibt nur zwei > Shiftoperationen. ... pro Bit und beide Shifts haben eine variablen Shiftanzahl. -> Assembler Code studieren. Wenn der µC keinen Shift mit einer variablen Anzahl an Stellen kann, artet das aus. Abgesehen davon, ist es dieselbe Grundidee wie die hier Beitrag "Re: 16Bit Variable Wertigkeit umdrehen" nur eben langsamer
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.