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

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.