Shuffelbits in einem Byte

Gast #1691420
Lesenswert?

Ich habe eine kleine Denksportaufgabe. Ich benoetige eine
Routine die alle Bits eines Bytes vertauscht. Also Bit7 wird
Bit0, bit6 nach bit1, bit0 nach bit7 usw.

Das hier ist mir eingefallen:

unsigned char shufflepixel(unsigned char pixel)
{
  return (
  ((pixel&0x80)>>7) | ((pixel&0x40)>>5) | ((pixel&0x20)>>3) | 
((pixel&0x10)>>1) |
  ((pixel&0x08)<<1) | ((pixel&0x04)<<3) | ((pixel&0x02)<<5) | 
((pixel&0x01)<<7)
    );

}

Das funktioniert natuerlich, aber da ich das brauche um bilder
in ein Format umzurechnen wie ein LCD es gerne haette, waere es
schoener wenn das ganze etwas schneller ginge. Vielleicht
kenn einer einen eleganten Trick?

Olaf
#1691438
Lesenswert?

Hmm.
Ohne das mit einem Profiler verifiziert zu haben.

Was hältst du von einer Tabelle, mit der du für ein Nibble des jeweils 
gespiegelte Nibble erhältst.

Das Byte in die Nibbles zerlegen, aus der Tabelle das 'Spiegelnibble' 
holen und die beiden Teilergebnisse gespiegelt zusammenbauen.
#1691471
Lesenswert?

Sowas hängt auch dann vom Prozessor ab, wenn der kein RBIT hat. So kann 
man bei AVRs in 2 Befehlen ein Bit testen und bedingt setzen, oder auch 
einfach über das T-Bit kopieren. Solche Schiebeoperationen sind bei AVRs 
wie auch jedem anderen Prozessor, der nur einzelbitweise schieben kann, 
jedoch sehr teuer, sollte man also vermeiden.

Je nach Prozessor kann es also weit sinnvoller so aussehen:
   r = 0;
   if (pixel & 0x01) r |= 0x80;
   if (pixel & 0x02) r |= 0x40;
   ...
Wenn der Compiler daraus das Richtige macht.

Tabelle ist natürlich dennoch schneller.
Gast #1691552
Lesenswert?

> Tabelle ist natürlich dennoch schneller.

Klar, aber das ist so die Holzhammermethode.

So rein optisch gefallen mir die beiden hier am besten:

  return( ((pixel * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL 
>> 32);
  return(((pixel * 0x0802LU & 0x22110LU) | (pixel * 0x8020LU & 
0x88440LU)) * 0x10101LU >> 16);

Ich muss morgen mal ausprobieren was am schnellsten ist. CPU ist im 
uebrigen kein AVR sondern ein R32C116. Da kann ich mir schon erlauben 
mit breiteren Datentypen rumzumachen.

Olaf

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