#1 26.05.2006 12:23:04

firlefanz
GodlikeMember
Ort: Olpe in NRW
Registriert: 31.01.2005
Beiträge: 1035
Web-Seite

Ungültige Gleitkommaoperation

Hallo,

wie kann der obige Fehler auftauchen und wie kann man den verhindern?

Mir hat ein CX User sein Errorlog geschickt, da steht der mehrfach drin,
jetzt muss ich den wenn möglich beheben aber ich weiß nicht genau, wo und wie ich den finde.

Ideen?

Danke,
Firle

Offline

 

#2 26.05.2006 12:33:04

Coolcat
ProGuru
Ort: Aachen, NRW
Registriert: 24.01.2005
Beiträge: 2780
Web-Seite

Re: Ungültige Gleitkommaoperation

1. Wie kommt den der Fehler ins Log? Fängst du Exceptions oder so? => Finde raus welche Exception genau...

2. Mögliche Ursachen:
· Division durch Null oder beinahe Null (z.B kleiner als 1 * 10^-70 )
· rechnen mit nicht initialisierten Variablen.
· ggf. auch rechnen mit den Zahlen NaN, +/- Infinity, etc....

Coolcat


My software never has bugs. It just develops random features.

Offline

 

#3 26.05.2006 12:38:07

firlefanz
GodlikeMember
Ort: Olpe in NRW
Registriert: 31.01.2005
Beiträge: 1035
Web-Seite

Re: Ungültige Gleitkommaoperation

Kann der sowohl bei Div als auch bei / auftauchen?

    procedure MyExceptionHandler(Sender : TObject; E : Exception );
    procedure ExceptionMsg(s: string);

Zitat:


procedure TCommandoForm.MyExceptionHandler(Sender: TObject; E: Exception);
var xini: tinifile;
    sec:  string;
begin
  sec:='Commando';
  inc(nerrorcount);
  if nerrorcount<1000 then begin
    try
      xini:=tinifile.create(sprogdir+'Errorlog.txt');
      xini.WriteString(sec,'Error'+inttostr(nerrorcount),datetostr(date)+' '+timetostr(time)+' '+e.Message);
      xini.free;
    except;
    end;
  end;
end;

procedure TCommandoForm.ExceptionMsg(s: string);
var xini: tinifile;
    sec:  string;
begin
  sec:='Commando';
  inc(nerrorcount);
  if nerrorcount<1000 then begin
    try
      xini:=tinifile.create(sprogdir+'Errorlog.txt');
      xini.WriteString(sec,s,'');
      xini.free;
    except;
    end;
  end;
end;

Danke,
Firle

Offline

 

#4 26.05.2006 12:42:42

firlefanz
GodlikeMember
Ort: Olpe in NRW
Registriert: 31.01.2005
Beiträge: 1035
Web-Seite

Re: Ungültige Gleitkommaoperation

PS: In Form.load:

Application.OnException:=MyExceptionHandler;

Was könnte ich denn noch da rein schreiben was mir bei der Lokalisierung der Fehler helfen könnte?

Firle

Offline

 

#5 26.05.2006 12:43:34

Coolcat
ProGuru
Ort: Aachen, NRW
Registriert: 24.01.2005
Beiträge: 2780
Web-Seite

Re: Ungültige Gleitkommaoperation

Zitat:

Kann der sowohl bei Div als auch bei / auftauchen?

Bei einer Gleitpunktdivision ist das Ergebnis immer der Wert 'NaN' (steht für "Not a Number"). Bei einer Integerdivision ist das Ergebnis soweit ich weiß undefiniert, da Integer keine reservierten Spezialwerte hat.
Da du aber den Fehler "Ungültige Gleitkommaoperation" bekommst, wird es sich vermutlich nicht um einen div-Operator handeln. wink


My software never has bugs. It just develops random features.

Offline

 

#6 26.05.2006 12:49:44

firlefanz
GodlikeMember
Ort: Olpe in NRW
Registriert: 31.01.2005
Beiträge: 1035
Web-Seite

Re: Ungültige Gleitkommaoperation

Okay, danke.

Eine Idee, wie ich mein Fehlerprotokoll erweitern/verbessern kann?

Firle

Offline

 

#7 26.05.2006 12:51:55

Coolcat
ProGuru
Ort: Aachen, NRW
Registriert: 24.01.2005
Beiträge: 2780
Web-Seite

Re: Ungültige Gleitkommaoperation

Zur lokalisierung solltet du vielleicht einfach am Anfang und Ende jeder wichtigen Methode einen Logeintrag machen. Dadurch findest du die richtige Methode in der der Fehler auftritt. Anschließend machst inerhalb dieser Methode z.B. alle 10 Zeilen einen Logeintrag. Wenn das nicht reicht eben jede Programmzeile....denkdran, nicht zuviele machen, du musst die später alle wieder rausmachen wink
In C++ kann man sich für solche Zwecke ein Marko definieren, welches automatisch Zeilennummer und Quellcode-Datei ausgibt. Das Marko kann man dann später einfach per #define abschalten und weg isses...

Achtung: Du brauchst für sowas am besten ein gebuffertes Logfile. Oder noch besser schreibst du das nur auf die Standardausgabe. Mit solchen Aktionen kann man sonst in wenigen Sekunden ein paar hundert MB Logfile produzieren....  yikes


My software never has bugs. It just develops random features.

Offline

 

#8 26.05.2006 12:53:43

firlefanz
GodlikeMember
Ort: Olpe in NRW
Registriert: 31.01.2005
Beiträge: 1035
Web-Seite

Re: Ungültige Gleitkommaoperation

Oje. Der manuelle Logeintrag, darauf bin ich auch schon gekommen, das ist aber tierisch umständlich, ich habe dermassen viel Code...

Mein Logfile hat max. 1000 Zeilen.

Offline

 

#9 26.05.2006 12:57:43

Coolcat
ProGuru
Ort: Aachen, NRW
Registriert: 24.01.2005
Beiträge: 2780
Web-Seite

Re: Ungültige Gleitkommaoperation

Also wir haben mit solchen Methoden EWAIN.e debuggt.....das hat über 14000 Zeilen Quellcode...
Wenn du die Einträge geschickt setzt kannst du das Problem sehr schnell eingrenzen. Ne Standardausgabe Ist besser als jeder Debugger.

Die 1000 Zeilen hast du nach ca. einer Millisekunde voll  :mrgreen: Wie gesagt, besser nicht auf Platte speichern


My software never has bugs. It just develops random features.

Offline

 

#10 05.06.2006 21:30:05

TheDon
Member
Registriert: 14.01.2006
Beiträge: 32

Re: Ungültige Gleitkommaoperation

Ich hätte da noch eine kleine Idee zu deinem Gleitkomma problem. Das problem könnte ein verändertes Statuswort der Gleitkommarecheneinheit der CPU sein. Zum Beispiel stellt Direct3D immer von Extended auf Single precision um, was sich dann bei Zeitberechnungen (mit Now, etc.) bemerkbar macht.
Gib einfach mal das CPU Gleitkomma Statuswort in deinem Execption Log aus. Leider hab ich grad kein Delphi installiert, um dir jetzt den genauen Befehl dafür zu sagen. Such mal nach DefaultCW, Get87CW oder so ähnlich in der Delphi Hilfe oder nach "delphi floating point status word" in groups.google.


TheDon

Offline

 

#11 11.07.2006 17:28:44

Visioner
ProMember
Registriert: 15.02.2006
Beiträge: 123

Re: Ungültige Gleitkommaoperation

Kann mich meinem Vorredner nur anschließen. Kenne das Problem. Es gibt die Möglichkeit die Gleitkomma - Überprüfung abzuschalten. Z.B. mit folgendem Befehl:  Set8087CW(DWord($133f)). Bei dem zu übergebendem Parameter habe ich verschiedene Einstellungen im Internet nachgelesen. Diese ($133f) hat sich bei mir in der Praxis am Besten bewährt (nur auf Intel getestet, aber 150 Systemen getestet). Es ist wichtig, zu mind. bei meiner selbstgeschriebenen Engine, diesen Befehl nach jedem RestoreDeviceObjects aufzufen, weil der Wert dadurch zurückgesetzt werden kann (habe ich damals nicht finden können. Bin in den MS DLL ausgestiegen).

In BDS2006 stehts sogar in der Hilfe.

BDS 2006 Hilfe:

Code: delphi

setzt das steuerwort in der floating point unit (fpu) und die in der unit system deklarierte variable noerrmsg .

[c++] void set8087cw (unsigned short newcw);


beschreibung 
ber das steuerwort in der gleitkommaeinheit werden die genauigkeit von gleitkommaberechnungen und der rundungsmodus festgelegt. auerdem bestimmt das steuerwort, ob bei bestimmten operationen mit gleitkommawerten exceptions ausgelst werden. weitere informationen finden sie in der prozessor-dokumentation von intel.
 
mit dieser routine knnen sie direkt auf das steuerwort des arithmetischen coprozessors zugreifen. denken sie aber daran, dass sich nderunggen auf die gleitkommaberechnungen in der gesamten anwendung auswirken. das steuerwort muss anschlieend wieder auf den alten wert gesetzt werden.
 
es ist zum beispiel empfehlenswert, alle gleitkomma-exceptions zu deaktivieren, wenn opengl zur darstellung von 3d-grafiken eingesetzt wird. rufen sie dazu (vor dem aufruf einer opengl-funktion) in der ereignisbehandlungsroutine fr oncreate des hauptformulars set8087cw(0x133f) auf.




Hoffe konnte auch mal helfen!

Visioner

PS: Suche DirectX Einstiegstutor, als Projektbegleitung auf Stundenbasis:
Themen: Matrix und Vectorenrechnung. Objekte und Objektgruppen im Raum anordnen und sich zueinander bewegen lassen. Raum Mainz-Bingen. Bei Interesse Mail an info@evivision.de

Offline

 

Brett Fußzeile

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson