Wie erzwinge ich 0.0 / 0.0 Null anstelle von NaN in MIPSPro C-Compiler zurück?

StackOverflow https://stackoverflow.com/questions/2563418

  •  23-09-2019
  •  | 
  •  

Frage

Wie die Frage Staaten, ich bin mit dem MIPSPRo C-Compiler, und ich habe eine Operation, die NaN für einige Datensätze, wo sowohl der Zähler und denom Null zurück. Wie verhindere ich, dass dies geschieht?

War es hilfreich?

Lösung

Auf SGI-Systemen mit dem MIPSPro Compiler, können Sie die Handhabung verschiedener Gleitkommaausnahmen mit großer Präzision mit den Einrichtungen in sigfpe.h gesetzt. Wie es passiert, ist die Aufteilung der Null durch Null ein solcher Fall:

#include <stdio.h>
#include <sigfpe.h>

int main (void) {
    float x = 0.0f;
    (void) printf("default %f / %f = %f\n", x, x, (x / x));
    invalidop_results_[_ZERO_DIV_ZERO] = _ZERO;
    handle_sigfpes(_ON, _EN_INVALID, 0, 0, 0);
    (void) printf("handled %f / %f = %f\n", x, x, (x / x));
    return 0;
}

Im Einsatz:


arkku@seven:~/test$ cc -version
MIPSpro Compilers: Version 7.3.1.3m
arkku@seven:~/test$ cc -o sigfpe sigfpe.c -lfpe
arkku@seven:~/test$ ./sigfpe
default 0.000000 / 0.000000 = nan0x7ffffe00
handled 0.000000 / 0.000000 = 0.000000

Wie Sie sehen können, ändert das _ZERO_DIV_ZERO Ergebnis Einstellung das Ergebnis der gleichen Abteilung. Ebenso können Sie regelmäßige Division durch Null behandeln (zum Beispiel, wenn Sie nicht unendlich als Ergebnis wollen).

Natürlich nichts davon ist Standard; es würde mehr tragbar sein für NaN nach jeder Teilung zu überprüfen und noch besser für Nullen zu überprüfen, bevor. C99 bietet eine gewisse Kontrolle über die Floating-Point-Umgebung in fenv.h, aber ich glaube nicht, etwas für diese verfügbar ist. Auf jedem Fall meine alte MIPSPro C99 nicht unterstützt.

Andere Tipps

Verwenden Sie eine if-Klausel? Ich bin auch neugierig, warum Sie diese mathematische Unmöglichkeit ignorieren wollen würde. Sie sicher, dass Ihre Eingabe ist nicht falsch / sinnlos in diesem Fall?

Wenn Sie nichts dagegen haben einen kleinen Fehler eingeführt wird, können Sie einen kleinen Wert auf den Nenner hinzufügen, vorausgesetzt, Sie Gleitkomma-Arithmetik tun. anscheinend haben einige kleine Werte definiert:

DBL_MIN ist die kleinste Doppel

DBL_EPSILON ist der kleinste Doppel S. T. x + DBL_EPSILON! = x

Also ich würde versuchen

#include <float.h>
#define EPS DBL_MIN

double divModified(double num, double denom) {
    return num / (denom + EPS);
}

IEEE 754 (die Spezifikation Punkt für floating) sagt, dass 0.0 / 0.0 ist keine Zahl, dh NaN. Wenn Sie wollen, dass es etwas anderes sein, bei weitem der beste Ansatz zu erkennen ist, wenn die Operanden beiden Nullen in einer if Klausel sind und den Wert zurückgeben, dass Sie lieber geben. Vielleicht so:

#define WonkyDiv(a,b)  ((a)==0.0&&(b)==0.0 ? 0.0 : (a)/(b))

float wonkyResult = WonkyDiv(numerator, denominator);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top