Wir alle wissen, 0/0
ist Undefined
und gibt einen Fehler zurück, wenn ich es in einen Taschenrechner stecke und wenn ich ein Programm (zumindest in C) erstelle, würde das Betriebssystem es beenden, wenn ich versuche, durch Null zu teilen.
Aber was ich mich gefragt habe, ist, ob der Computer überhaupt versucht, durch Null zu teilen , oder ob er nur "eingebauten Schutz" hat, sodass er, wenn er "sieht" 0/0
, einen Fehler zurückgibt, noch bevor er versucht, ihn zu berechnen?
math
error-handling
arithmetic
Ankush
quelle
quelle
Antworten:
Die CPU hat eine integrierte Erkennung. Die meisten Befehlssatzarchitekturen geben an, dass die CPU einen Ausnahmebehandler für die Ganzzahldivision durch Null abfängt (ich denke nicht, dass es wichtig ist, wenn die Dividende Null ist).
Es ist möglich, dass die Prüfung auf einen Nullteiler in der Hardware parallel mit dem Versuch, die Teilung durchzuführen, erfolgt. Die Erkennung des fehlerhaften Zustands löscht jedoch effektiv die Teilung und fängt stattdessen ab, sodass wir nicht wirklich sagen können, ob ein Teil vorhanden ist davon versuchte die Teilung oder nicht.
(Hardware funktioniert oft so, indem sie mehrere Dinge parallel ausführt und anschließend das entsprechende Ergebnis auswählt, da dann alle Vorgänge sofort gestartet werden können, anstatt bei der Auswahl des entsprechenden Vorgangs zu serialisieren.)
Der gleiche Trap-to-Exception-Mechanismus wird auch verwendet, wenn die Überlauferkennung aktiviert ist. Dies wird normalerweise durch die Verwendung verschiedener Add / Sub / Mul-Anweisungen (oder eines Flags in diesen Anweisungen) angefordert.
Die Gleitkommadivision hat auch die Erkennung für die Division durch Null integriert, gibt jedoch einen anderen Wert zurück ( IEEE 754 gibt NaN an ), anstatt eine Ausnahmebehandlung abzufangen.
Hypothetisch gesehen könnten die folgenden Probleme auftreten, wenn die CPU keine Erkennung für den Versuch einer Division durch Null aufweist:
quelle
Dies hängt von der Sprache, dem Compiler, der Verwendung von Ganzzahlen oder Gleitkommazahlen usw. ab.
Für Gleitkommazahlen verwenden die meisten Implementierungen den IEEE 754- Standard, bei dem die Division durch 0 gut definiert ist. 0/0 ergibt ein genau definiertes Ergebnis von NaN (keine Zahl), und x / 0 für x ≠ 0 ergibt entweder + Infinity oder -Infinity, abhängig vom Vorzeichen von x.
In Sprachen wie C, C ++ usw. ruft die Division durch Null undefiniertes Verhalten auf. Entsprechend der Sprachdefinition kann also alles passieren. Vor allem Dinge, die Sie nicht passieren wollen. Wie alles, was perfekt funktioniert, wenn Sie den Code schreiben und Daten zerstören, wenn Ihr Kunde sie verwendet. Also tun Sie dies aus sprachlicher Sicht nicht . Einige Sprachen garantieren, dass Ihre Anwendung abstürzt. Es liegt an ihnen, wie dies umgesetzt wird. Bei diesen Sprachen stürzt die Division durch Null ab.
Viele Prozessoren haben eine Art eingebauten "Divide" -Befehl, der sich je nach Prozessor unterschiedlich verhält. Auf Intel 32-Bit- und 64-Bit-Prozessoren führen die "Divide" -Anweisungen zu einem Absturz Ihrer Anwendung, wenn Sie versuchen, durch Null zu dividieren. Andere Prozessoren verhalten sich möglicherweise anders.
Wenn ein Compiler feststellt, dass beim Ausführen von Code eine Division durch Null auftritt und der Compiler nett zu seinen Benutzern ist, gibt er wahrscheinlich eine Warnung aus und generiert eine eingebaute "Divide" -Anweisung, damit das Verhalten dementsprechend ist gleich.
quelle
EXCEPTION_INT_DIVIDE_BY_ZERO
Wert, derEXCEPTION_RECORD
vom (hoffentlich) installierten Structed Exception Handling HandlerScheint, als würden Sie sich fragen, was passieren würde, wenn jemand eine CPU baut, die vor dem Teilen nicht explizit auf Null prüft. Was passieren würde, hängt ganz von der Implementierung der Division ab. Ohne auf Details einzugehen, würde eine Art von Implementierung ein Ergebnis erzeugen, bei dem alle Bits gesetzt sind, z. B. 65535 auf einer 16-Bit-CPU. Ein anderer könnte auflegen.
quelle
Da
x/0
der Punkt keinen Sinn ergibt, müssen Computer immer auf Division durch Null prüfen. Hier gibt es ein Problem: Programmierer wollen rechnen,(a+b)/c
ohne prüfen zu müssen, ob diese Berechnung überhaupt Sinn macht. Die Reaktion unter der Haube auf die Division durch Null durch CPU + Zahlentyp + Betriebssystem + Sprache besteht darin, entweder etwas ziemlich drastisches zu tun (z. B. das Programm zum Absturz zu bringen) oder etwas übermäßig Gutes zu tun (z. B. einen Wert zu erstellen, der Nein ergibt Sinn wie der IEEE-GleitkommawertNaN
, eine Zahl, die "keine Zahl" ist).In einer gewöhnlichen Umgebung muss ein Programmierer wissen, ob dies
(a+b)/c
sinnvoll ist. In diesem Zusammenhang gibt es keinen Grund, die Division durch Null zu überprüfen. Wenn eine Division durch Null auftritt und die Maschinensprache + die Implementierungssprache + der Datentyp + das Betriebssystem darauf reagieren, um das Programm zum Absturz zu bringen, ist das in Ordnung. Wenn die Antwort darin besteht, einen Wert zu erstellen, der eventuell jede Zahl im Programm verschmutzt, ist das auch in Ordnung.Weder "etwas Drastisches" noch "übermäßig Gutes" ist in der Welt des Hochzuverlässigkeits-Computing das Richtige. Diese Standardantworten können einen Patienten töten, ein Verkehrsflugzeug zum Absturz bringen oder eine Bombe am falschen Ort explodieren lassen. In einer hochzuverlässigen Umgebung wird ein Programmierer, der schreibt
(a+b)/c
, während der Codeüberprüfung oder in der heutigen Zeit von einem Tool, das nach verbotenen Konstrukten sucht, automatisch zu Tode gerissen. In dieser Umgebung sollte der Programmierer stattdessen etwas in der Art geschrieben habendiv(add(a,b),c)
(und möglicherweise nach dem Fehlerstatus suchen). Unter der Haube schützen diediv
(und auch dieadd
) Funktionen / Makros vor einer Division durch Null (oder einem Überlauf beiadd
). Was dieser Schutz beinhaltet, ist sehr umsetzungsspezifisch.quelle
Das wissen wir inzwischen
x/0
und0/0
haben keine genau definierten Antworten. Was passiert, wenn Sie0/0
trotzdem versuchen zu berechnen ?Auf einem modernen System wird die Berechnung an die MPU in der CPU übergeben und als unzulässige Operation gekennzeichnet, die zurückkehrt
NaN
.Auf einem viel älteren System, wie z. B. Heimcomputern der 80er Jahre, die keine On-Chip-Unterteilung hatten, wurde die Berechnung von jeder Software durchgeführt, die ausgeführt wurde. Es gibt einige Möglichkeiten:
0
1
log(0)
und die Software verwendet entweder ihre Fehlerbehandlungsroutinen oder stürzt ab0
und e 0 = 1, was ein Ergebnis von ergibt1
Mit anderen Worten, es wäre implementierungsabhängig, was passieren würde, und es wäre möglich, Software zu schreiben, die für jeden Wert korrekte und vorhersehbare Ergebnisse liefert, für
0/0
die es jedoch seltsame Werte gibt, die dennoch intern konsistent sind.quelle
NaN
Ganzzahlen.very inefficient
für die Division sind. Die Kosten für die Arithmetik betragen (Addition = Subtraktion) <= Multiplikation <= Division. Wenn Sie keine MPU haben, die Division in der gleichen Anzahl von Taktzyklen wie Addition (normalerweise eine) ausführen kann, ist Division teurer als Addition und Subtraktion und normalerweise auch teurer als Multiplikation.