Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Warum keine Exception bei Division durch 0 (https://www.delphipraxis.net/34212-warum-keine-exception-bei-division-durch-0-a.html)

Jelly 19. Nov 2004 11:10


Warum keine Exception bei Division durch 0
 
Hallo,

ich bastle an einem größeren Projekt, und hab irgendwie einen Fehler im Code, was höchstwahrscheinlich durch eine Division durch 0 zurückzuführen ist. Deshalb hab ich jetzt einmal testweise folgenden Code probiert:

Delphi-Quellcode:
procedure TForm1.cmdNullClick(Sender: TObject);
var
 mu : double ;
begin
     mu := 5/0 ;
end;
rsp.
Delphi-Quellcode:
procedure TForm1.cmdNullClick(Sender: TObject);
var
 mu : double ;
begin
     mu := 0/0 ;
end;
Jetzt wundere ich mich aber, warums nicht knallt, wenn der Code ausgeführt. es passiert rein garnichts, und eventuell folgender Code wird normal weiter ausgeführt. Wieso gibts da keine Exception? Stattdessen zeigt ein
Delphi-Quellcode:
showmessage (FloatToStr(5/0)) ;
mir ein INF an, ein
Delphi-Quellcode:
showmessage (FloatToStr(0/0)) ;
ein NAN. Mathematisch ist wohl klar, aber mein gutes alte Turbo Pascal hat da immer eine Laufzeitfehlermeldung ausgegeben. Ich hab in den Delphi Einstellung bischen gekuckt, aber nirgends einen Schalter gefunden, der dieses Verhalten erklärt.

Gruß,
Tom

SubData 19. Nov 2004 11:36

Re: Warum keine Exception bei Division durch 0
 
Ich glaub Delphi knallt nur raus, wenn du das mit nem Interger versuchst... Float / Double müsste gehen... Oder täusch ich mich da jetzt?

Chewie 19. Nov 2004 11:39

Re: Warum keine Exception bei Division durch 0
 
Ist bei Fließkommazahlen schon richtig so. Such mal hier nach Hier im Forum suchenNaN (Not A Number), da solltest du die Erklärung kriegen.

Jelly 19. Nov 2004 13:01

Re: Warum keine Exception bei Division durch 0
 
Hmm. Gibts denn ne Möglichkeit, via Compilerschalter o.ä. trotzdem ne Exception herbeizurufen. Hintergrund des Ganzen ist eine Monte Carlo Simulation, welche (wie es mir scheint), zu 99,999% und mehr funktionniert, nur ab und zu mir mit dieser Division durch 0 Probleme machen könnt. Bin halt noch auf der Fehlersuche... Ich halt vermeiden, bei jeder Division ein if...then...else zu schreiben, weil mir das definitiv zu aufwendig wird. Die ganze Simulation hat mittlerweilen paar tausend Zeilen Code, wo solche Division theoretisch relativ oft auftreten können... Zeile für Zeile das Ganze zu debuggen macht keinen Sinn, weil die ganze Rechnung ja zu 99,999% funktioniert.

jim_raynor 19. Nov 2004 13:04

Re: Warum keine Exception bei Division durch 0
 
Achja. Mit diesem Problem kämpfe ich auch schon längere Zeit und habe noch keine Lösung gefunden. Man kann mal probieren das ControlWord der FPU zu ändern. Geht relativ einfach mit der JCL. Weiss jetzt nicht, wie die Unit/Funktion genau heisst aber glaube irgendwas mit 8087.

Jelly 19. Nov 2004 13:08

Re: Warum keine Exception bei Division durch 0
 
Zitat:

Zitat von jim_raynor
ControlWord der FPU zu ändern

In dem Satz versteh ich nur "der", "zu" und "ändern" :stupid:

Was bitte schön ist ein Controlword und eine FPU?

Hansa 19. Nov 2004 13:09

Re: Warum keine Exception bei Division durch 0
 
Damit das Programm nur noch auf einer CPU läuft ? Ich würde einen anderen Zahlentyp testen: BCD oder so ähnlich. Mußt halt suchen. :mrgreen:

jim_raynor 19. Nov 2004 13:13

Re: Warum keine Exception bei Division durch 0
 
Okay. FPU bedeutet Floating Point Unit und ist quasi die CPU für alle Gleitkommaberechnungen (ist natürlich in der CPU integriert). Durch das ControlWord kann die FPU gesteuert werden, was denn bei Fehlern wie Division durch 0 passieren soll.

Luckie 19. Nov 2004 13:14

Re: Warum keine Exception bei Division durch 0
 
Dein Beispiel-Code wird gar nicht ausgeführt. Der Compiler ist ja nicht blöd, er sieht, dass du die Varaible nie benutzt und optimiert sie weg.

SubData 19. Nov 2004 13:19

Re: Warum keine Exception bei Division durch 0
 
Prüf doch einfach ob die Zahl <> 0 ist, dann brauchste auch keine Exception mehr :)

Jelly 19. Nov 2004 13:22

Re: Warum keine Exception bei Division durch 0
 
OK, ich glaub das Problem ist doch nicht so tragisch.

Delphi-Quellcode:
procedure TForm1.cmd1Click(Sender: TObject);
var
 a, b, c, d : double ;
begin
     a := 0 ;
     b := 0 ;
     c := a/b ;  // -> hier krieg ich ne Exception ;
     d := 0/0 ;  // -> und hier nicht
     showmessage (floatToStr(c)) ;
end;
0/0 akzeptiert er also, a/b zum Glück nicht. Da in meinem Programm natürlich nirgends direkt 0/0 steht, sondern ich eben nur mit Variablen arbeit, müsst ich in der Simulation natürlich eine Exception kriegen. Da dies aber nicht der Fall ist, muss ich den Fehler wohl sonstwo suchen.

Gruß,


EDIT: Danke noch an alle, und Luckies Erklärung scheint mir sehr einleuchtend..

Luckie 19. Nov 2004 13:35

Re: Warum keine Exception bei Division durch 0
 
d := 0/0 wird wieder wegoptimiert. Guck mal, ob ein blauer Punkt vor der Zeile am Rand ist.

Jelly 19. Nov 2004 13:38

Re: Warum keine Exception bei Division durch 0
 
Zitat:

Zitat von Luckie
Guck mal, ob ein blauer Punkt vor der Zeile am Rand ist.

Nöö, ist keiner. Womit ich jetzt auchverstanden hätt, was diese blaue Punkte überhaupt bedeuten :mrgreen:

woki 19. Nov 2004 14:10

Re: Warum keine Exception bei Division durch 0
 
Hi,

also nochmal zusammenfassend, damit auch flüchtige zukünftige Leser das richtig verstehen:

Selbstverständlich löst Delphi bei Division durch Null immer auch bei allen Gleitkommazahlen einen Laufzeitfehler (EZeroDivide) aus.
Da eine Division durch Null mathematisch gar nicht definiert ist, was sollte Delphi denn da auch für ein Ergebnis zurückliefern.
Aber Voraussetzung ist natürlich, daß der Code überhaupt ausgeführt wird, und nicht z.B. vom Optimizer wegoptimiert wurde. Von daher ist es sehr sinnvoll, beim Debuggen den Optimizer abzuschalten,
und wenn man nicht debugged beim Entwickeln den Debugger auszuschalten, das kostet nämlich eventuell sehr viel Rechenzeit. Ein Hinweis noch: Wenn einem die IDE zu langsam wird, gibt es noch einige Dinge, die man abschalten kann, wenn man sie gerade nicht braucht.

Grüße
Woki

Hansa 19. Nov 2004 16:13

Re: Warum keine Exception bei Division durch 0
 
Zitat:

Zitat von Luckie
Dein Beispiel-Code wird gar nicht ausgeführt. Der Compiler ist ja nicht blöd, er sieht, dass du die Varaible nie benutzt und optimiert sie weg.

Luckie, das war echt gut. :thumb: Ist mir gar nicht aufgefallen. Da sieht man mal wieder, daß man sich auch zu Tode optimieren kann. :mrgreen:

Robert Rossmair 24. Nov 2004 16:16

Re: Warum keine Exception bei Division durch 0
 
Zitat:

Zitat von woki
Selbstverständlich löst Delphi bei Division durch Null immer auch bei allen Gleitkommazahlen einen Laufzeitfehler (EZeroDivide) aus.

Falsch. Weder löst Delphi die Exception aus, noch wird diese immer ausgelöst:
- Fließkommaarithmetik wird von der Fließkommaeinheit des Prozessors (der FPU) ausgeführt, die den IEEE-Standard 754 implementiert (http://grouper.ieee.org/groups/754/). Es ist auch die FPU, die ggf. eine Exception wirft. Delphi verpackt diese nur ansprechend.
- Fließkomma-Exceptions lassen sich in der FPU ausmaskieren, die Unit Jcl8087 stellt dazu Funktionen zur Verfügung. Ist eine Exception maskiert, wird statt dessen ein Flag im Statuswort der FPU gesetzt (Jcl8087: GetPending8087Exceptions) und evtl. ein spezieller Wert zurückgeliefert. Siehe dazu auch die Erläuterungen zum Typ JclMath.TFloatingPointClass in der Online Hilfe der JCL.
Die Exception bleibt latent, bis entweder die Maskierung aufgehoben wird, oder die latenten Exceptions gelöscht werden (Jcl8087: ClearPending8087Exceptions). Hebt man die Maskierung auf, ohne die Löschung vorzunehmen, dann werden die latenten Exceptions ausgelöst - evtl. an einer Stelle im Code, die nichts mit der Ursache zu tun hat.
Zitat:

Zitat von woki
Da eine Division durch Null mathematisch gar nicht definiert ist, was sollte Delphi denn da auch für ein Ergebnis zurückliefern.

+/-Unendlich, falls Zähler <> 0, oder ein NaN (not a number), falls Zähler = 0.
Zitat:

Zitat von woki
Aber Voraussetzung ist natürlich, daß der Code überhaupt ausgeführt wird, und nicht z.B. vom Optimizer wegoptimiert wurde.

Dass im gegebenen Fall irgendwelcher Beispielcode nicht kompiliert wird, ist ganz unerheblich. Es gäbe in keinem Fall eine Exception, weil zur Laufzeit(!) keine Division ausgeführt wird. Ausdrücke, die ausschließlich Konstanten enthalten, rechnet nämlich der Compiler aus.

- Robert


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