2012-10-28 11 views
7

Ich habe eine Frage zu den nächsten Code:Division durch Null - C-Programmierung

int main { 
double x = 0; 
double y = 0/x; 

if(y==1) {.....} 
.... 
.... 
return 0; 
} 

Wenn ich den Code auf meinem Computer laufen, bekomme ich keine Laufzeitfehler und ich sehe, dass y = -nan(0x8000000000000). Warum ist es kein Laufzeitfehler, durch Null zu teilen?

Zusätzlich, wenn ich die erste Zeile zu int x = 0; jetzt ändern, gibt es einen Laufzeitfehler. Was ist der Unterschied?

+3

@Jens: Nein, Anhang F des C99-Standards überschreibt dies und Sie erhalten kein undefiniertes Verhalten für Fließkomma. Nicht alle Implementierungen unterstützen Anhang F, aber deins und meins. –

Antwort

9

Der Grund, warum Sie keine Ausnahme oder Fehler erhalten, ist, weil für ein Doppel unendlich und NaN definiert sind (siehe IEEE floating point), aber wenn Sie das gleiche für Integer versuchen, erhalten Sie einen Fehler, weil NaN/Infinity aren 't definiert

+2

Sie erhalten nicht immer einen Fehler für die Ganzzahl '0/0', dies hängt von der Implementierung ab. –

+0

@DietrichEpp: Genauer hängt es von der CPU ab. –

+0

@ JanHudec: Nicht unbedingt. –

13

Sie können nicht auf diese "arbeiten" (dh die gleiche Sache die ganze Zeit, portabel) überhaupt, es ist undefiniertes Verhalten in C für den zweiten Fall, und auch für die erste, wenn Ihre Implementierung definiert nicht __STDC_IEC_559__ (das ist, glaube ich, selten in diesen Tagen).

C99, §6.5.5/5

Das Ergebnis des/Operators ist der Quotient aus der Division des ersten Operanden von den zweiten ; Das Ergebnis des% -Operators ist der Rest. Wenn in beiden Operationen der Wert der zweite Operand Null ist, ist das Verhalten nicht definiert.

Die Tatsache, Sie bekommen ein „Not a Number“ in einem Fall und und nicht in dem anderes ist, dass man in Gleitkomma-Arithmetik durchgeführt wird, wo auf Ihrer Implementierung (nach IEEE 754 Division konform Semantik von Null), 0/0 ergibt ein NaN.

Im zweiten Fall verwenden Sie Ganzzahlarithmetik – undefiniertes Verhalten, es gibt keine Vorhersage, was passieren wird.

+0

Es sollte hinzugefügt werden, dass das beobachtete Verhalten von der Plattform definiert wird. Ix86 passiert zufällig die Division durch Null. –

+3

Das ist eigentlich falsch für die meisten Systeme: C99, §F.1: "Eine Implementierung, die' __STDC_IEC_559__' definiert, muss den Spezifikationen in diesem Anhang entsprechen. Wo eine Verbindung zwischen der C-Sprache und IEC 60559 angegeben ist, spezifiziert die IEC60559 Verhalten wird durch Bezugnahme übernommen, sofern nicht anders angegeben. " §F.3 "Die Operatoren' + ',' -', '*' und '/' stellen die Operationen IEC 60559 zum Addieren, Subtrahieren, Multiplizieren und Dividieren bereit. " –

+0

@DietrichEpp: besser jetzt? – Mat

4

Dies liegt daran, IEEE 754 Standard definiert spezielle Werte für positive und negative Unendlichkeit zusammen mit "keine Zahl" für Fließkommawerte.

Nicht-Fließkomma-Typen wie int haben diese speziellen Werte nicht definiert und daher wird die Laufzeit aufgrund eines nicht behandelten Fehlers beendet.

Dies ist nicht C-spezifisch, Sie werden ein sehr ähnliches (wenn nicht das gleiche) Verhalten in anderen Sprachen sehen, einfach weil diese Funktionalität auf Hardware zurückzuführen ist.

Verwandte Themen