Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi CompToStr (https://www.delphipraxis.net/33845-comptostr.html)

engel 13. Nov 2004 17:36


CompToStr
 
Liebe Leute,

habe noch Delphi3, das kein Int64 kennt, möchte aber aus einer 64-Bit Zahl des Typs Comp (den gibt's wenigstens) einen string[19] machen. IntToStr geht gar nicht (comp wird in Delphi als Float behandelt), FloatToStrF(xxx,ffFixed,18,0) ist ungeeignet, weil bei großen Zahlen gerundet + das Format gewechselt wird. Z.B. wird aus FloatToStrF(xxx,ffFixed,18,0) '4.6385934037476E18' erzeugt - die letzten Stellen fallen weg, obwohl der Wertebereich von Comp bis 9.223.372.036.854.775.807 geht.
Leider ist der Wertebereich von 'fbstp st' auch geringer (das wär' ne einfache Lösung).

Wie man die 8 Byte der Comp-Variable im Speicher 'findet', weiß ich, aber wie bekomme ich aus diesen 8 'einzelnen' Bytes dann einen string[19], ohne mit riesigen Zahlen zu hantieren (was ja eben nicht funktioniert)?

Nothine 13. Nov 2004 18:37

Re: CompToStr
 
Bei Google suchenCompToStr
direkt im ersten eintrag gibt's ne CompToStr funktion :roll:

engel 14. Nov 2004 16:06

Re: CompToStr
 
Danke! - das war wohl zu leicht? - Wie sieht's denn mit meiner letzten Frage aus (würd' mich trotzdem interessieren).
Falls noch einer die Funktion "CompToStr" (vom WebLink oben) benutzen will: Da ist ein kleiner Fehler drin:

type CompStr = string[25]; {Comps have up to 18 digits, plus commas, and sign}

richtig wäre (ausprobiert):

type CompStr = string[26]; {Comps have up to 19 digits, plus (<=6) commas, and sign}
{-9.223.372.036.854.775.808 to 9.223.372.036.854.775.807}

noch 'ne Korrektur: ich meinte oben natürlich nicht "fbstp st", sondern "fbstp mem80".

Hat einer den Quelltext der funktion StrToInt für Int64 - das wird hier doch sicher ohne Fließkommarechnung gemacht? :?:

Nothine 21. Nov 2004 17:17

Re: CompToStr
 
ich weiß nicht ob du bereits eine bessere lösung gefunden hast, aber ich hab mich in den letzten tagen mal etwas stärker mit dem thema comp auseinandergesetzt, und herausgekommen ist diese funktion(-sansammlung):

Delphi-Quellcode:
{ unterstützende Funktionen: }

const cwChop: Word = $1F32;

procedure Int;
asm
  SUB    ESP,$02
  FSTCW  WORD PTR [ESP]
  FWAIT
  FLDCW  cwChop
  FRNDINT
  FWAIT
  FLDCW  WORD PTR [ESP]
  ADD    ESP,$02
end;

function CompMod10(C: Comp): Byte;
const Ten: Integer = $0A;
asm
  ADD    ESP,-$04
  FILD   QWORD PTR [ESP+$0C]
  FIDIV  DWORD PTR [TEN]
  FST
  CALL   Int
  FSUBP
  FIMUL  DWORD PTR [TEN]
  FISTP  DWORD PTR [ESP]
  POP    EAX
  AND    EAX,$FF
  CMP    AL,$0A
  JB     @@End
  NEG    AL
@@End:
end;

function CompDivMod10(var C: Comp): Byte;
const Ten: Integer = $0A;
asm
  PUSH   DWORD PTR [EAX+$04] // bzw.:
  PUSH   DWORD PTR [EAX]    // 
  FILD   QWORD PTR [EAX]    // function CompDivMod10(...): Byte;
  FIDIV  DWORD PTR [TEN]    // begin
  CALL   Int                //   Result := CompMod10(C);
  FISTP  QWORD PTR [EAX]    //   C := Int(C/10); // System.Int
  CALL   CompMod10           // end;
end;

function CompLen(C: Comp): Byte;
const Ten: Integer = $0A;
asm
  PUSH   EDX                   // bzw.:
  SUB    ESP,$02                //
  FSTCW  WORD PTR [ESP]        // function CompLen(...): Byte;
  FLDCW  WORD PTR [cwChop]     // begin
  BT     DWORD PTR [ESP+$12],31 //   Result := Byte(C < 0);
  SETB   DL                    //   repeat
@@Loop:                         //     Inc(Result);
  INC    DL                    //     C := Int(C / 10); // System.Int
  FILD   QWORD PTR [ESP+$0E]   //   until C = 0;
  FIDIV  DWORD PTR [TEN]       // end;
  FRNDINT
  FISTP  QWORD PTR [ESP+$0E]
  BSR    EAX,DWORD PTR [ESP+$12]
  JNZ    @@Loop
  BSR    EAX,DWORD PTR [ESP+$0E]
  JNZ    @@Loop
  MOVZX  EAX,DL
  FLDCW  WORD PTR [ESP]
  ADD    ESP,$02
  POP    EDX
end;

{ Die Hauptfunktion: }

function CompToStr(C: Comp): string;
var I: Integer;
begin
  SetLength(Result,CompLen(C));
  if C < 0 then Result[1] := '-';
  I := Length(Result);
  repeat
    Result[I] := Char( CompDivMod10(C) + 48);
    Dec(I);
  until C = 0;
end;
hab mir allerdings verkniffen 1000er-Trennzeichen einzubauen :roll: (ich find die sehn blöd aus :stupid:)

engel 21. Nov 2004 17:31

Re: CompToStr
 
...danke, das seh' ich mir mal genauer an. :coder2:

Nothine 21. Nov 2004 17:54

Re: CompToStr
 
kein problem :-D wenn du fragen dazu hast nur keine falsche scheu :stupid:


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:36 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-2025 by Thomas Breitkreuz