AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Library: Algorithmen Delphi Integer Werte in Binärstring umwandeln
Thema durchsuchen
Ansicht
Themen-Optionen

Integer Werte in Binärstring umwandeln

Ein Thema von Amateurprofi · begonnen am 15. Apr 2006
Antwort Antwort
Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.063 Beiträge
 
Delphi XE2 Professional
 
#1

Integer Werte in Binärstring umwandeln

  Alt 15. Apr 2006, 05:54
Da dieses Thema immer mal wieder angesprochen wird, und weil ich gerade eine solche Funktion brauchte, habe ich
zwei Assembler Funktionen geschrieben, die integer bzw int64 Werte in Binärstrings umwandeln.
Das ganze läßt sich natürlich auch in Pascal leicht realisieren, jedoch sind diese Funktionen deutlich schneller.
Über Verbessererungsvorschläge und/oder Kritik freute ich mich.

Delphi-Quellcode:
{------------------------------------------------------------------------------}
{ IntToBin  (integer)                                                          }
{ Wandelt value in einen String mit der Länge len um, der die unteren len Bits }
{ von value in binärer Darstellung zeigt.                                      }
{ Wenn len<=0 oder len>32 ist, entscheidet die Position des höchsten 1-Bits    }
{ in value über die Länge des Strings, wobei aber, wenn value leer ist,        }
{ mindestens ein Zeichen ausgegeben wird                                       }
{------------------------------------------------------------------------------}
FUNCTION IntToBin(value,len:integer):string;
const bits:array[0..63] of char=
         '0000000100100011010001010110011110001001101010111100110111101111';
asm
               // EAX Wert
               // EDX Länge
               // ECX Zeiger Result
               push edi
               mov edi,ecx // Zeiger auf Result
               or edx,edx
               je @DefineLen // len = 0, benötigte Länge holen
               cmp edx,32
               jbe @Start // 0 < len <= 32
@DefineLen: bsr edx,eax // Index höchstes Bit in Value
               jnz @AdjustLen
               xor edx,edx
@AdjustLen: add edx,1
@Start: push eax // value
               mov eax,edi // Zeiger Result
               call System.@LStrSetLength
               mov edi,[edi] // Zeiger String
               mov ecx,[edi-4] // Länge
               pop eax // value
               sub ecx,4
               jc @EndDW // weniger als 4 bits
               // Jeweils 4 Bits umwandeln
@LoopDW: mov edx,eax
               and edx,$F
               mov edx,DWORD [bits+edx*4]
               mov [edi+ecx],edx
               shr eax,4
               je @FillZero
               sub ecx,4
               jnc @LoopDW // nochmal 4 Bits
@EndDW: // Restline 1..3 Bytes
               and eax,$F
               mov eax,DWORD [bits+eax*4]
               cmp cl,$FE
               ja @3Bytes
               je @2Bytes
               jnp @End
               rol eax,8
               mov [edi],al
               jmp @End
@2Bytes: shr eax,16
               mov [edi],ax
               jmp @End
@3Bytes: mov [edi],ah
               shr eax,16
               mov [edi+1],ax
               jmp @End
               // Mit 0en auffüllen
               // ECX = Anzahl
@FillZero: mov eax,'0000'
               mov edx,ecx
               shr ecx,2
               rep stosd
               mov ecx,edx
               and ecx,3
               rep stosb
@End: pop edi
end;

{------------------------------------------------------------------------------}
{ IntToBin  (int64)                                                            }
{ Wandelt value in einen String mit der Länge len um, der die unteren len Bits }
{ von value in binärer Darstellung zeigt.                                      }
{ Wenn len<=0 oder len>64 ist, entscheidet die Position des höchsten 1-Bits    }
{ in value über die Länge des Strings, wobei aber, wenn value leer ist,        }
{ mindestens ein Zeichen ausgegeben wird                                       }
{------------------------------------------------------------------------------}
FUNCTION IntToBin(value:int64; len:integer):string;
const bits:array[0..63] of char=
         '0000000100100011010001010110011110001001101010111100110111101111';
asm
               // EAX Länge
               // EDX Zeiger Result
               // [EBP+8] = LoValue
               // [EBP+12] = HiValue
               push ebx
               push edi
               mov edi,edx // Zeiger Result
               mov ebx,[ebp+8] // LoValue
               mov ecx,[ebp+12] // HiValue
               // len prüfen
               mov edx,eax
               or edx,edx
               je @DefineLen // len = 0, benötigte Länge holen
               cmp edx,64
               jbe @Start
@DefineLen: mov eax,33
               bsr edx,ecx // EAX=Höchstes Bit in HiValue
               jnz @AdjustLen // HiValue nicht leer
               mov eax,1
               bsr edx,ebx // EAX=Höchstes Bit in LoValue
               jnz @AdjustLen // LoValue nicht leer
               xor edx,edx
@AdjustLen: add edx,eax // Länge=BitPos+1
@Start: mov eax,edi // Zeiger Result
               call System.@LStrSetLength
               mov edi,[edi] // Zeiger String
               mov ecx,[edi-4] // Länge
               mov edx,[ebp+12] // HiValue
               // Jeweils 4 Bits umwandeln
@LoopDW: sub ecx,4
               jc @EndDW // weniger als 4 bits
               mov eax,ebx // LoValue
               and eax,$F
               mov eax,DWORD [bits+eax*4]
               mov [edi+ecx],eax
               shrd ebx,edx,4 // Value 4 Bits nach unten
               shr edx,4
               jne @LoopDW // HiValue nicht leer
               or ebx,ebx
               jne @LoopDW // LoValue nicht leer
               // Mit 0en auffüllen
@FillZero: mov eax,'0000'
               mov edx,ecx
               shr ecx,2
               rep stosd
               mov ecx,edx
               and ecx,3
               rep stosb
               jmp @End
@EndDW: // Restline 1..3 Bytes
               and ebx,$F
               mov eax,DWORD [bits+ebx*4]
               cmp cl,$FE
               ja @3Bytes
               je @2Bytes
               jnp @End
               rol eax,8
               mov [edi],al
               jmp @End
@2Bytes: shr eax,16
               mov [edi],ax
               jmp @End
@3Bytes: mov [edi],ah
               shr eax,16
               mov [edi+1],ax
@End: pop edi
               pop ebx
end;
Hagen hat folgende Alternativen gepostet:
Delphi-Quellcode:
function IntToBIN(Value: Cardinal): String;
var
  I: Integer;
begin
  Result := StringOfChar('0', 32);
  I := 32;
  while Value <> 0 do
  begin
    if Odd(Value) then Result[I] := '1';
    Dec(I);
    Value := Value shr 1;
  end;
end;

function IntToBIN(Value: Cardinal): String;
var
  I: Integer;
begin
  Result := StringOfChar('0', 32);
  I := 32;
  while Value <> 0 do
  begin
    Result[I] := Char(Ord('0') + Ord(Odd(Value)));
    Dec(I);
    Value := Value shr 1;
  end;
end;

function IntToBIN(Value: Cardinal): String;
const
  cChar: array[Boolean] of Char = ('0', '1');
var
  I: Integer;
  M: Cardinal;
begin
  SetLength(Result, 32);
  M := 1;
  for I := 32 downto 1 do
  begin
    Result[I] := cChar[Value and M <> 0];
    Inc(M, M);
  end;
end;

function IntToBIN(Value: Cardinal): String;
const
  cChar: array[Boolean] of Char = ('0', '1');
var
  I: Integer;
begin
  SetLength(Result, 32);
  for I := 1 to 32 do
  begin
    Result[I] := cChar[Value and $80000000 <> 0];
    Inc(Value, Value);
  end;
end;

function IntToBIN(Value: Cardinal): String;
var
  I: Integer;
begin
  SetLength(Result, 32);
  for I := 1 to 32 do
  begin
    Result[I] := Char(Ord('0') + (Value shr 31));
    Inc(Value, Value);
  end;
end;

function IntToBIN(Value: Cardinal): String;
var
  I: Integer;
begin
  Result := StringOfChar('0', 32);
  I := 1;
  while Value <> 0 do
  begin
    if Value and $80000000 <> 0 then Result[I] := '1';
    Inc(I);
    Inc(Value, Value);
  end;
end;
[edit=Chakotay1308]Code aktualisiert und Hagen's Alternativen hinzugefügt. Mfg, Chakotay1308[/edit]
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat
Antwort Antwort

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz