![]() |
Schnelle SwapByte Routine - Bits swappen
Hi Leute,
anbei eine kleine "Lookup" Tabelle, die die Bitreihenfolge innerhalb eines Bytes mittels Case-Anweisung swapt. Gegebenenfalls spart sich so jemand Tipparbeit :)
Delphi-Quellcode:
Gruß,
function SwapByte (Const Value : Byte) : Byte;
begin case Value of $00 : Result := $00; $01 : Result := $80; $02 : Result := $40; $03 : Result := $C0; $04 : Result := $20; $05 : Result := $A0; $06 : Result := $60; $07 : Result := $E0; $08 : Result := $10; $09 : Result := $90; $0A : Result := $50; $0B : Result := $D0; $0C : Result := $30; $0D : Result := $B0; $0E : Result := $70; $0F : Result := $F0; $10 : Result := $08; $11 : Result := $88; $12 : Result := $48; $13 : Result := $C8; $14 : Result := $28; $15 : Result := $A8; $16 : Result := $68; $17 : Result := $E8; $18 : Result := $18; $19 : Result := $98; $1A : Result := $58; $1B : Result := $D8; $1C : Result := $38; $1D : Result := $B8; $1E : Result := $78; $1F : Result := $F8; $20 : Result := $04; $21 : Result := $84; $22 : Result := $44; $23 : Result := $C4; $24 : Result := $24; $25 : Result := $A4; $26 : Result := $64; $27 : Result := $E4; $28 : Result := $14; $29 : Result := $94; $2A : Result := $54; $2B : Result := $D4; $2C : Result := $34; $2D : Result := $B4; $2E : Result := $74; $2F : Result := $F4; $30 : Result := $0C; $31 : Result := $8C; $32 : Result := $4C; $33 : Result := $CC; $34 : Result := $2C; $35 : Result := $AC; $36 : Result := $6C; $37 : Result := $EC; $38 : Result := $1C; $39 : Result := $9C; $3A : Result := $5C; $3B : Result := $DC; $3C : Result := $3C; $3D : Result := $BC; $3E : Result := $7C; $3F : Result := $FC; $40 : Result := $02; $41 : Result := $82; $42 : Result := $42; $43 : Result := $C2; $44 : Result := $22; $45 : Result := $A2; $46 : Result := $62; $47 : Result := $E2; $48 : Result := $12; $49 : Result := $92; $4A : Result := $52; $4B : Result := $D2; $4C : Result := $32; $4D : Result := $B2; $4E : Result := $72; $4F : Result := $F2; $50 : Result := $0A; $51 : Result := $8A; $52 : Result := $4A; $53 : Result := $CA; $54 : Result := $2A; $55 : Result := $AA; $56 : Result := $6A; $57 : Result := $EA; $58 : Result := $1A; $59 : Result := $9A; $5A : Result := $5A; $5B : Result := $DA; $5C : Result := $3A; $5D : Result := $BA; $5E : Result := $7A; $5F : Result := $FA; $60 : Result := $06; $61 : Result := $86; $62 : Result := $46; $63 : Result := $C6; $64 : Result := $26; $65 : Result := $A6; $66 : Result := $66; $67 : Result := $E6; $68 : Result := $16; $69 : Result := $96; $6A : Result := $56; $6B : Result := $D6; $6C : Result := $36; $6D : Result := $B6; $6E : Result := $76; $6F : Result := $F6; $70 : Result := $0E; $71 : Result := $8E; $72 : Result := $4E; $73 : Result := $CE; $74 : Result := $2E; $75 : Result := $AE; $76 : Result := $6E; $77 : Result := $EE; $78 : Result := $1E; $79 : Result := $9E; $7A : Result := $5E; $7B : Result := $DE; $7C : Result := $3E; $7D : Result := $BE; $7E : Result := $7E; $7F : Result := $FE; $80 : Result := $01; $81 : Result := $81; $82 : Result := $41; $83 : Result := $C1; $84 : Result := $21; $85 : Result := $A1; $86 : Result := $61; $87 : Result := $E1; $88 : Result := $11; $89 : Result := $91; $8A : Result := $51; $8B : Result := $D1; $8C : Result := $31; $8D : Result := $B1; $8E : Result := $71; $8F : Result := $F1; $90 : Result := $09; $91 : Result := $89; $92 : Result := $49; $93 : Result := $C9; $94 : Result := $29; $95 : Result := $A9; $96 : Result := $69; $97 : Result := $E9; $98 : Result := $19; $99 : Result := $99; $9A : Result := $59; $9B : Result := $D9; $9C : Result := $39; $9D : Result := $B9; $9E : Result := $79; $9F : Result := $F9; $A0 : Result := $05; $A1 : Result := $85; $A2 : Result := $45; $A3 : Result := $C5; $A4 : Result := $25; $A5 : Result := $A5; $A6 : Result := $65; $A7 : Result := $E5; $A8 : Result := $15; $A9 : Result := $95; $AA : Result := $55; $AB : Result := $D5; $AC : Result := $35; $AD : Result := $B5; $AE : Result := $75; $AF : Result := $F5; $B0 : Result := $0D; $B1 : Result := $8D; $B2 : Result := $4D; $B3 : Result := $CD; $B4 : Result := $2D; $B5 : Result := $AD; $B6 : Result := $6D; $B7 : Result := $ED; $B8 : Result := $1D; $B9 : Result := $9D; $BA : Result := $5D; $BB : Result := $DD; $BC : Result := $3D; $BD : Result := $BD; $BE : Result := $7D; $BF : Result := $FD; $C0 : Result := $03; $C1 : Result := $83; $C2 : Result := $43; $C3 : Result := $C3; $C4 : Result := $23; $C5 : Result := $A3; $C6 : Result := $63; $C7 : Result := $E3; $C8 : Result := $13; $C9 : Result := $93; $CA : Result := $53; $CB : Result := $D3; $CC : Result := $33; $CD : Result := $B3; $CE : Result := $73; $CF : Result := $F3; $D0 : Result := $0B; $D1 : Result := $8B; $D2 : Result := $4B; $D3 : Result := $CB; $D4 : Result := $2B; $D5 : Result := $AB; $D6 : Result := $6B; $D7 : Result := $EB; $D8 : Result := $1B; $D9 : Result := $9B; $DA : Result := $5B; $DB : Result := $DB; $DC : Result := $3B; $DD : Result := $BB; $DE : Result := $7B; $DF : Result := $FB; $E0 : Result := $07; $E1 : Result := $87; $E2 : Result := $47; $E3 : Result := $C7; $E4 : Result := $27; $E5 : Result := $A7; $E6 : Result := $67; $E7 : Result := $E7; $E8 : Result := $17; $E9 : Result := $97; $EA : Result := $57; $EB : Result := $D7; $EC : Result := $37; $ED : Result := $B7; $EE : Result := $77; $EF : Result := $F7; $F0 : Result := $0F; $F1 : Result := $8F; $F2 : Result := $4F; $F3 : Result := $CF; $F4 : Result := $2F; $F5 : Result := $AF; $F6 : Result := $6F; $F7 : Result := $EF; $F8 : Result := $1F; $F9 : Result := $9F; $FA : Result := $5F; $FB : Result := $DF; $FC : Result := $3F; $FD : Result := $BF; $FE : Result := $7F; $FF : Result := $FF; end; end; Peter |
AW: Schnelle SwapByte Routine - Bits swappen
Oder man spart sich die Tipparbeit auf andere Weise:
Delphi-Quellcode:
function SwapByte(B: Byte): Byte;
var i: Integer; begin Result := 0; for i:= 0 to 7 do Result := Result or (((b shr i) and 1) shl (7-i)); end; |
AW: Schnelle SwapByte Routine - Bits swappen
Oder definiere und benutze
Delphi-Quellcode:
const
swapbyte: array[byte] of byte = ( $00, $80, $40, $C0, $20, $A0, $60, $E0, $10, $90, $50, $D0, $30, $B0, $70, $F0, $08, $88, $48, $C8, $28, $A8, $68, $E8, $18, $98, $58, $D8, $38, $B8, $78, $F8, $04, $84, $44, $C4, $24, $A4, $64, $E4, $14, $94, $54, $D4, $34, $B4, $74, $F4, $0C, $8C, $4C, $CC, $2C, $AC, $6C, $EC, $1C, $9C, $5C, $DC, $3C, $BC, $7C, $FC, $02, $82, $42, $C2, $22, $A2, $62, $E2, $12, $92, $52, $D2, $32, $B2, $72, $F2, $0A, $8A, $4A, $CA, $2A, $AA, $6A, $EA, $1A, $9A, $5A, $DA, $3A, $BA, $7A, $FA, $06, $86, $46, $C6, $26, $A6, $66, $E6, $16, $96, $56, $D6, $36, $B6, $76, $F6, $0E, $8E, $4E, $CE, $2E, $AE, $6E, $EE, $1E, $9E, $5E, $DE, $3E, $BE, $7E, $FE, $01, $81, $41, $C1, $21, $A1, $61, $E1, $11, $91, $51, $D1, $31, $B1, $71, $F1, $09, $89, $49, $C9, $29, $A9, $69, $E9, $19, $99, $59, $D9, $39, $B9, $79, $F9, $05, $85, $45, $C5, $25, $A5, $65, $E5, $15, $95, $55, $D5, $35, $B5, $75, $F5, $0D, $8D, $4D, $CD, $2D, $AD, $6D, $ED, $1D, $9D, $5D, $DD, $3D, $BD, $7D, $FD, $03, $83, $43, $C3, $23, $A3, $63, $E3, $13, $93, $53, $D3, $33, $B3, $73, $F3, $0B, $8B, $4B, $CB, $2B, $AB, $6B, $EB, $1B, $9B, $5B, $DB, $3B, $BB, $7B, $FB, $07, $87, $47, $C7, $27, $A7, $67, $E7, $17, $97, $57, $D7, $37, $B7, $77, $F7, $0F, $8F, $4F, $CF, $2F, $AF, $6F, $EF, $1F, $9F, $5F, $DF, $3F, $BF, $7F, $FF); |
AW: Schnelle SwapByte Routine - Bits swappen
Ich finde "den" richtig nice...:
Delphi-Quellcode:
procedure MirrorByte(A : byte) : byte;
var B,C,D,F : Uint64; begin B := $0080200802; C := $0884422110; D := $0101010101; F := A; F := F * B; F := F and C; F := F * D; F := F shr 32; Result := F and $FF; end; Kann man natürlich in eine Zeile schreiben aber so sieht man die Bits wandern... Mavarik |
AW: Schnelle SwapByte Routine - Bits swappen
@Mavarik
+1 Darüber muss ich mal nachdenken :-) |
AW: Schnelle SwapByte Routine - Bits swappen
Verstehe ich da was nicht richtig?
Delphi-Quellcode:
????
Result := (Value shl 4) or (Value shr 4);
|
AW: Schnelle SwapByte Routine - Bits swappen
Zitat:
|
AW: Schnelle SwapByte Routine - Bits swappen
In richtig kurz hätte ich noch einen zu bieten:
b := ((b * $0202020202) and $010884422010) mod 1023; dürfte aber wegen 64bit und modulo relativ langsam sein. dann hätte ich noch den: b := (((b and $aa) shr 1) + ((b and $55) shl 1)); b := (((b and $cc) shr 2) + ((b and $33) shl 2)); b := ((b shr 4) + (b shl 4)); ser sollte in Summe eigentlich recht schnell sein(natürlich nicht so schnell wie das Look-Up) und sollte auch recht speichersparend sein(okay, ich gebe es ja zu: ist auf nem PC nicht nötig, aber....) |
AW: Schnelle SwapByte Routine - Bits swappen
Wirklich
Delphi-Quellcode:
und nicht
+
Delphi-Quellcode:
?
or
|
AW: Schnelle SwapByte Routine - Bits swappen
Hi Leute, danke für die Rückmeldungen :)
sollte nicht die Case hier den höchsten Speed liefern? Mir ist klar, dass ich shiften kann, und das es semantisch "elegantere" Konstrukte gibt.... :-D |
AW: Schnelle SwapByte Routine - Bits swappen
![]() |
AW: Schnelle SwapByte Routine - Bits swappen
Zitat:
Kann durchwegs sein, mal sehen wie sich das auf die Laufzeit / generierten Code auswirkt. Habe dieses Uralt-Beispiel heute mal meinem jungen Mitarbeiter (IT Azubi und zudem Sohn) gezeigt, als Antwort auf die Frage, wozu Case eigentlich gut sei .... |
AW: Schnelle SwapByte Routine - Bits swappen
Beim Case wird jeder einzelne Wert verglichen, bis etwas getroffen wird.
Beim Array wird der Eingabewert direkt als Index/Offset verwendet. |
AW: Schnelle SwapByte Routine - Bits swappen
Zitat:
Da gibts dann auch keinen so großen Unterschied zu einem direkten Zugriff auf ein Array. Wobei der direkte Zugriff sicherlich immernoch ein Stückchen schneller (und in meinen Augen) schöner zu lesen ist als das gigantische case-of. Notwendig ist ein case-of nicht, aber für Aufzählungswerte oder oft auch für Zahlenwerte ist es manchmal eine etwas übersichtlichere Alternative zu einer endlosen if-then-else Verkettung. |
AW: Schnelle SwapByte Routine - Bits swappen
Hätte noch etwas vermutlich ganz schnelles:
Code:
MOVZX AX, BYTE PTR[a]
RCR AL,1 RCL AH,1 RCR AL,1 RCL AH,1 RCR AL,1 RCL AH,1 RCR AL,1 RCL AH,1 RCR AL,1 RCL AH,1 RCR AL,1 RCL AH,1 RCR AL,1 RCL AH,1 RCR AL,1 RCL AH,1 MOV BYTE PTR[a],AH |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:03 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz