16Bit Variable Wertigkeit umdrehen

Gast #498618
Lesenswert?

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 !
Gast #498636
Lesenswert?

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
Gast #498754
Lesenswert?

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]);

#498765
Lesenswert?

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.
Moderator Persönliche Seite #498790
Lesenswert?

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.
#499151
Lesenswert?

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.
Gast #1613634
Lesenswert?

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
#1614151
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren