Teilung durch Nullprävention

8

Was ist 1.#INF und warum verhindert Casting auf float oder double eine Division durch 0 des Absturzes?
Auch, irgendwelche großartigen Ideen, wie man Teilung durch 0 verhindern kann? (Wie jedes Makro oder Vorlage)?

%Vor%

wenn ich stattdessen verwende:

%Vor%     
Vinicius Horta 02.07.2012, 19:30
quelle

3 Antworten

12

1.#INF ist eine positive Unendlichkeit. Sie erhalten es, wenn Sie einen positiven Gleitkommawert durch Null teilen (wenn Sie den Gleitkommawert selbst durch Null teilen, wird das Ergebnis "keine Zahl" sein).

Wenn Sie andererseits eine Ganzzahl durch Null teilen, stürzt das Programm ab.

Der Grund dafür, dass float fZero = 2 / nQuota; abstürzt, liegt darin, dass beide Operanden des Operators / ganze Zahlen sind, also wird die Division für Ganzzahlen ausgeführt. Es spielt keine Rolle, dass Sie das Ergebnis dann in einem Float speichern. C ++ hat keine Vorstellung von der Zieltypisierung.

Warum die positive Unendlichkeit, die auf eine ganze Zahl geworfen wird, die kleinste ganze Zahl ist, habe ich keine Ahnung.

    
fredoverflow 02.07.2012, 19:34
quelle
3
  

Warum verhindert die Verwendung von (float) oder (double) eine Division durch 0 des Absturzes?

Es muss nicht unbedingt sein. Der Standard ist erstaunlich, wenn es um Floating Point geht. Die meisten Systeme verwenden heutzutage den IEEE-Gleitkomma-Standard, und das besagt, dass die Standardaktion für die Division durch Null darin besteht, ± unendlich zurückzugeben und nicht abzustürzen. Sie können es zum Absturz bringen, indem Sie die entsprechenden Gleitkommaausnahmen aktivieren.

Beachten Sie: Das Gleitkommaausnahme-Modell und das C ++ - Ausnahme-Modell haben nur das Wort "Ausnahme" gemeinsam. Auf jeder Maschine, an der ich arbeite, löst eine Gleitkommaausnahme keine C ++ - Ausnahme aus.

  

Auch irgendwelche großartigen Ideen, wie man Teilung durch 0 verhindert?

  1. Einfache Antwort: Tu es nicht.
    Das ist einer von denen "Doktor, Doktor tut weh, wenn ich das tue!" Arten von Situationen. Also tu es nicht!

  2. Stellen Sie sicher, dass der Divisor nicht Null ist.
    Überprüfen Sie die Divisoren, die Benutzereingaben sind, auf Plausibilität. Filtern Sie Ihre Benutzereingaben immer auf Gesundheit. Ein Benutzereingabewert von Null, wenn die Zahl in Millionen sein soll, wird neben dem Überlauf alle Arten von Chaos verursachen. Überprüfen Sie die Zwischenwerte auf Plausibilität.

  3. Aktivieren Sie Gleitkommaausnahmen.
    Das Standardverhalten so zu machen, dass Fehler (und das sind fast immer Fehler) ungeprüft passieren, war IMHO ein großer Fehler seitens des Normenausschusses. Benutze den Standard und diese Unendlichkeiten und Nicht-a-Zahlen werden schließlich alles zu einem Inf oder einem NaN machen.
    Der Standardwert sollte sein, Gleitkommafehler in ihren Spuren zu stoppen, mit einer Option, um Dinge wie 1.0 / 0.0 und 0.0 / 0.0 zu erlauben. Das ist nicht der Fall, also musst du diese Fallen aktivieren. Tun Sie das und Sie können oft die Ursache des Problems in kurzer Zeit finden.

  4. Schreibe benutzerdefinierte Dividieren, benutzerdefinierte Multiplikation, benutzerdefinierte Quadratwurzel, benutzerdefinierte Sinus, ... Funktionen.
    Dies ist leider der Weg, den viele sicherheitskritische Softwaresysteme nehmen müssen. Es ist ein königlicher Schmerz. Option # 1 ist out, weil es nur Wunschdenken ist. Option # 3 ist aus, weil das System nicht abstürzen darf. Option # 2 ist immer noch eine gute Idee, aber es funktioniert nicht immer, weil schlechte Daten immer einen Weg haben, sich einzuschleichen. Es ist Murphys Gesetz.

BTW, das Problem ist ein bisschen schlechter als nur Division durch Null. 10 200 / 10 -200 wird ebenfalls überlaufen.

    
David Hammen 02.07.2012 20:28
quelle
1

Normalerweise überprüfen Sie, ob Sie nicht durch Null teilen. Der folgende Code ist nicht besonders nützlich, es sei denn, nQuota hat einen legitimen Wert, verhindert aber Abstürze

%Vor%     
Chris McKnight 02.07.2012 19:39
quelle

Tags und Links