Frage

Ich bin meinen Code über den folgenden Befehl kompilieren:

icc -ltbb test.cxx -o test

Dann, wenn ich das Programm ausführen:

time ./mp6 100 > output.modified
Floating exception
4.871u 0.405s 0:05.28 99.8%     0+0k 0+0io 0pf+0w

ich ein "Floating exception" erhalten. Dieser folgenden ist der Code in C ++, dass ich vor der Ausnahme hatte und nach:

// before
if (j < E[i]) {
   temp += foo(0, trr[i], ex[i+j*N]);
}

// after
temp += (j < E[i])*foo(0, trr[i], ex[i+j*N]);

Dies ist die Boolesche Algebra ... so (j

int foo(int s, int t, int e) {
    switch(s % 4) {
        case 0:
            return abs(t - e)/e;
        case 1:
            return (t == e) ? 0 : 1;
        case 2:
            return (t < e) ? 5 : (t - e)/t;
        case 3:
            return abs(t - e)/t;
    }
    return 0;
}

foo () ist keine Funktion, die ich schrieb, damit ich bin mir nicht sicher, was es tut ... aber ich glaube nicht, das Problem mit der Funktion foo (). Gibt es etwas, über Boolesche Algebra, dass ich verstehe, oder etwas nicht, die anders in C ++ funktioniert als ich kenne? Irgendwelche Ideen, warum dies eine Ausnahme verursacht?

Danke, Hristo

War es hilfreich?

Lösung

Sie werden mit ziemlicher Sicherheit von Null in foo geteilt wird.

Ein einfaches Programm von

int main()
{
    int bad = 0;
    return 25/bad;
}

auch Drucke

Floating point exception

auf meinem System.

Also, sollten Sie prüfen, ob e 0 ist, wenn s % 4 Null ist, oder ob t 0 ist, wenn s % 4 2 oder 3 ist dann zurück, was Wert sinnvoll für Ihre Situation macht, anstatt zu teilen versuchen, durch Null.


@hristo: C ++ wird prüfen, noch die rechte Seite einer Multiplikation auch wenn die linke Seite Null ist. Es spielt keine Rolle, dass das Ergebnis sollte Null; es zählt, dass foo genannt wurde und ausgewertet und einen Fehler verursacht.

Beispiel Quelle:

#include <iostream>
int maybe_cause_exception(bool cause_it)
{
    int divisor = cause_it ? 0 : 10;
    return 10 / divisor;
}

int main()
{
    std::cout << "Do not raise exception: " << maybe_cause_exception(false) << std::endl;

    int x = 0;

    std::cout << "Before 'if' statement..." << std::endl;

    if(x)
    {
        std::cout << "Inside if: " << maybe_cause_exception(true) << std::endl;
    }

    std::cout << "Past 'if' statement." << std::endl;

    std::cout << "Cause exception: " << x * maybe_cause_exception(true) << std::endl;

    return 0;
}

Ausgabe:

Do not raise exception: 1

Before 'if' statement...

Past 'if' statement.

Floating point exception

Andere Tipps

Ist es möglich, dass Sie von 0 sind Dividieren? Es könnte sein, dass eine ganze Division durch 0 wird als „Floating exception“ auftauchen.

Wenn Sie die if haben, wird die Berechnung nicht durchgeführt, wenn eine Division durch 0 passieren würde. Wenn Sie das „Boolesche Algebra“ tun, wird die Berechnung unabhängig gemacht, um 0 Fehler in einer Kluft führt.

Sie denken, dass es temp += 0*foo(...); sein wird, so dass es nicht zu nennen foo benötigt (da 0 mal etwas wird immer 0 sein), aber das ist nicht, wie der Compiler funktioniert. Beide Seiten eines * haben bewertet werden.

Während ich Ihnen nicht sagen, die genaue Ursache der Floating-Point-Ausnahme kann ich einige Informationen, die Sie nützlich finden könnten Gleitkommazahlen Fehler Zukunft bei der Untersuchung. Ich glaube, Mark hat schon etwas Licht auf, warum diese haben besonderes Problem dar.


Die meist tragbare Art und Weise zu bestimmen, ob eine Fließkommaausnahmebedingung aufgetreten ist, und die Ursache ist die Floating-Point-Ausnahme Einrichtungen von C99 in fenv.h . Es gibt 11 Funktionen definiert in fenv.h zum Manipulieren der Gleitkommazahl Umgebung (siehe FENV (3) man-Seite ). Sie können auch dieser Artikel von Interesse sein.


Auf POSIX-konformen Systemen wird SIGFPE ein Verfahren gesendet wird, wenn in eine fehlerhafte führt arithmetische Operation, und dies muss nicht unbedingt beinhalten Gleitkommaarithmetik. Wenn das SIGFPE Signal behandelt und SA_SIGINFO in der sa_flags für den Aufruf von sigaction(2) sollte das si_code Mitglied der siginfo_t Struktur den Grund für den Fehler an.

Von der wikipedia SIGFPE Artikel :

Eine gemeinsame Aufsicht ist die einzige Quelle der SIGFPE Bedingungen Division durch Null zu betrachten. Auf einigen Architekturen (IA-32 enthielt [Bearbeiten] ), Integer-Division von INT_MIN, der kleinsten darstellbaren negativen ganzzahligen Wert von -1 Trigger das Signal, da der Quotient, eine positive Zahl ist nicht darstellbare .

Wenn ich mit Multiplikation mit einem oder null ersetzt Zweig vorgeschlagen, das habe ich nicht prüfen, ob Aussagen gegen numerische Ausnahme bewacht werden. Multiplikation Trick wertet noch Ausdruck, aber wirft es effektiv entfernt. für klein genug Ausdruck ist ein solcher Trick besser als bedingt, aber Sie müssen sicher Ausdruck machen auswerten kann.

Sie können nach wie vor Multiplikation Trick verwenden, wenn Sie etwas Nenner verwandeln. statt x/t Verwendung x/(t + !t), die keinen Einfluss auf alles, wenn Nenner nicht Null ist (Sie hinzufügen Null dann) aber erlaubt Nenner t = 0 berechnen zu sein, und dann weggeworfen durch von Null multipliziert wird.

Und sorry, aber mit meinen Vorschlägen vorsichtig sein, ich weiß nicht, alle Details des Programms. plus, neige ich dazu, gehen wild über Zweige mit „cleveren“ Boolesche Ausdrücke ersetzt

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top