2017-12-02 7 views
5

Ich bin überrascht, nicht die Division durch Null-Ausnahme erhalten. Wie bekomme ich es zurück?Delphi Berlin 10.1 Division durch Null-Ausnahme fehlt

Berlin 10.1 jüngstes installieren, neues Projekt,

procedure TForm1.Button1Click(Sender: TObject); 
var 
    a: Double; 
begin 
    a := 5/0;      // No exception 
    ShowMessage(a.ToString);  // -> 'INF' 
end; 
+1

Bestätigt auf meiner Kopie von Berlin. Sieht so aus, als wäre es auch in Tokio: https://community.embarcadero.com/answers/divide-by-zero-different-in-rad-studio-10-2 –

+6

@Jerry: Das liegt daran, dass der Ausdruck ein konstanter Ausdruck ist und zur Laufzeit nicht berechnet. Mindestens eine der beiden Zahlen (Dividend, Divisor) muss eine Variable sein, um eine Ausnahme auszulösen. –

+2

Großartig! Compiler weiß, wie man durch 0 teilt :) – Victoria

Antwort

7
a := 5/0; 

Der Ausdruck 5/0 ist, in der Fachsprache ausgedrückt, ein constant expression.

Ein konstanter Ausdruck ist ein Ausdruck, den der Compiler auswerten kann, ohne das Programm auszuführen, in dem er auftritt. Konstante Ausdrücke enthalten Ziffern; Zeichenketten; wahre Konstanten; Werte von aufgezählten Typen; die speziellen Konstanten Wahr, Falsch und Null; und Ausdrücke, die ausschließlich aus diesen Elementen mit Operatoren, Typumwandlungen und Mengenkonstruktoren erstellt werden.

Als solche wird dieser Ausdruck vom Compiler ausgewertet und nicht zur Laufzeit. Ihre Auswertung wird also durch Kompilierzeitregeln bestimmt und kann nicht durch Runtime-Gleitkommaeinheit-Ausnahmemasken beeinflusst werden.

Und diese Regeln geben an, dass der positive Wert geteilt durch Null gleich +INF ist, ein spezieller IEEE754-Wert. Wenn Sie den Ausdruck so ändern, dass er mindestens ein Argument enthält, das kein Konstantenausdruck ist, wird er zur Laufzeit ausgewertet, und es wird eine Division durch Null-Ausnahme ausgelöst.

4

Sie können die Ausnahmen sind Floating-Point-Steuerung ausgelöst, um die SetExceptionMask Funktion in Math-Einheit mit: http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Math.SetExceptionMask

Um alle Gleitkomma-Ausnahmen zu deaktivieren verwenden:

SetExceptionMask(exAllArithmeticExceptions); 

Um alle Gleitkomma-Ausnahme Nutzung zu ermöglichen:

Beachten Sie auch, dass der Compiler in Ihrem Beispielcode den Wert zur Kompilierzeit bestimmt (da der Ausdruck konstant ist), so dass er unabhängig vom an SetExceptionMask übergebenen Wert keine Ausnahme auslöst. Auslösen Ausnahme benötigen Sie einen etwas komplexeren Beispiel, so etwas wie dieses:

program test; 
uses Math; 
var 
    xx,yy: double; 
begin 
SetExceptionMask([]); 
xx := 1; 
yy := 0; 
halt(round(xx/yy)); 
end. 
+0

Und um * nur * eine Division durch Zero Ausnahme zu aktivieren, tun Sie etwas wie: 'SetExceptionMask (GetExceptionMask - [exZeroDivide]);'. –

+3

Wenigstens der erste Teil dieser Antwort hat keinen Einfluss auf die gestellte Frage –

+3

@DavidHeffernan In einer Diskussion über Gleitkommaausnahme, die nicht auslöst, denke ich, dass es wichtig ist, SetExceptionMask zu erwähnen. Sicher, es war vielleicht nicht der Grund in der OPs-Code, aber oft Code hier veröffentlicht wurde als zu viel vereinfacht und der echte Code könnte Variablen verwendet haben. –

Verwandte Themen