Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Int64-Überlauf erkennen / Registerabfrage (https://www.delphipraxis.net/162184-int64-ueberlauf-erkennen-registerabfrage.html)

archimedix 11. Aug 2011 10:42

Int64-Überlauf erkennen / Registerabfrage
 
Hallo,

gibt es eine Möglichkeit zu erkennen, ob bei einer Rechenoperation mit Int64-Typen ein Überlauf aufgetreten ist?

Und zwar das ganze nicht über den Overflowcheck des Compilers, sondern z.B. über eine Auswertung der Prozessorregister.

Ich kenne mich mit asm leider nicht aus und weiß daher nicht, was die CPU in irgendwelchen Flag-Registern im Falle eines Überlaufs hinterlässt und wie man das abfragen kann. Wer kann mir hier weiterhelfen?

gammatester 11. Aug 2011 11:27

AW: Int64-Überlauf erkennen / Registerabfrage
 
Knifflig. Wenn Du überhaupt eine Chance haben will, mußt Du wahrscheinlich Deine ganzen Rechnungen in elementare Schritte aufteilen und nach jeden Schritt prüfen. Beispiel:
Delphi-Quellcode:
var
  x,y: int64;
begin
  x := $7fffffffabcd1234;
  y := x + $7890abcd; // Overflow erkennbar
  y := ((x+ $7890abcd) - $7890abcd) + 1; //**
end;
In ** ist nach der Zuweisung kein Overflow erkennbar, effektiv ist das ja y := x +1. Aber es sind ja eigentlich zwei Overflows aufgetreten.

archimedix 11. Aug 2011 11:40

AW: Int64-Überlauf erkennen / Registerabfrage
 
Aufteilung in elementare Schritte und Prüfung nach jedem Schritt wäre kein Problem, ist genau das, was ich machen möchte!

(wollte man erst am Ende einer längeren Rechung festellen, ob irgendwo ein Überlauf aufgetreten ist, wäre wahrscheinlich die try-Except-Variante bei eingeschalteter Überlaufprüfung durch den Compiler das praktischste...)

sirius 11. Aug 2011 11:59

AW: Int64-Überlauf erkennen / Registerabfrage
 
über Register wäre so:

Delphi-Quellcode:
function getFlags:Integer;
asm
  pushfd
  pop eax
end;



procedure TForm1.Button1Click(Sender: TObject);
var x:int64;
begin
  x:=$7FFFFFFFFFFFFFFF;
  x:=x+1;
  if (getFlags and ($800))<>0 then  //$800 : Testen der Flags ob OL gesetzt ist
    showmessage('Überlauf: '+inttostr(x));
end;

archimedix 11. Aug 2011 12:02

AW: Int64-Überlauf erkennen / Registerabfrage
 
Danke, das sieht schon ganz gut aus.

Kann man das auch als inline-Funktion mit boolschem Rückgabewert realisieren?

sirius 11. Aug 2011 12:06

AW: Int64-Überlauf erkennen / Registerabfrage
 
Delphi-Quellcode:
function isOLFlag:boolean;
asm
  pushfd
  pop eax
  and eax,$800
  shr eax,11
end;
inline hat mein D7 nicht, musst du mal testen.

Memnarch 11. Aug 2011 12:07

AW: Int64-Überlauf erkennen / Registerabfrage
 
Delphi-Quellcode:
function IsOverFlow(): Boolean;
begin
  Result := (getFlags and ($800))<>0;
end;
So sollte es klappen, wen man GetFlags hier wiederverwendet.

EDIT: mist sirius war schneller^^

MFG
Memnarch

archimedix 11. Aug 2011 12:12

AW: Int64-Überlauf erkennen / Registerabfrage
 
Hallo !

Danke, Problem gelöst!!


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:23 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