Forum: Compiler & IDEs 16Bit Variable Wertigkeit umdrehen


von pluto (Gast)


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 !

von Blackbird (Gast)


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

von Karl H. (kbuchegg)


Lesenswert?

  val = ( ((uint16_t)val) >> 8 ) | ( val << 8 );

von gast (Gast)


Lesenswert?

Buchegger:

einen swap meinte er nicht

von pluto (Gast)


Lesenswert?

@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.

von Martin Schneider (Gast)


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


von Karl H. (kbuchegg)


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.

von Rahul, der Trollige (Gast)


Lesenswert?

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...

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Detlef _. (detlef_a)


Lesenswert?

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

von horst (Gast)


Lesenswert?

wie waere es mit

    val ^ 0b1111111111111111  ( eor 0xffff ) ?

gruss
       horst

von Rahul, der Trollige (Gast)


Lesenswert?

>val ^ 0b1111111111111111  ( eor 0xffff ) ?

da kommt das gleiche raus wie bei ~val...

von Jan M. (mueschel)


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.

von Martin (Gast)


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

von Karl H. (kbuchegg)


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

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
Noch kein Account? Hier anmelden.