2016-05-25 20 views
3

Ich spiele mit Gleitkommaarithmetik, und ich stieß auf etwas, das erklärt werden muss.C - Hinzufügen von zwei Gleitkommazahlen mit einfacher Genauigkeit, Ergebnis kann nicht unendlich sein

Wenn Rundungsmodus auf ‚gegen Null‘, auch bekannt als:

fesetround(FE_TOWARDZERO); 

und das Hinzufügen von verschiedenen Arten von normalen positiven Zahlen, kann ich nie Unendlichkeit erreichen.

Es ist jedoch aus dem ieee 745 bekannt, dass ein Überlauf in die Unendlichkeit aus der Addition endlicher Zahlen resultieren kann.

Zum Beispiel:

#include <fenv.h> 
#include <stdio.h> 

float hex2float (int hex_num) { 
    return *(float*)&hex_num; 
} 

void main() { 
    int a_int = 0x7f7fffff; // Maximum finite single precision number, about 3.4E38 
    int b_int = 0x7f7fffff; 
    float a = hex2float(a_int); 
    float b = hex2float(b_int); 
    float res_add; 

    fesetround(FE_TOWARDZERO); // need to include fenv.h for that 
    printf("Calculating... %+e + %+e\n",a,b); 
    res_add = a + b; 
    printf("Res = %+e\n",res_add); 
} 

Wenn ich jedoch Rundungsmodus für andere etwas verändern, könnte ich eine + INF als Antwort bekommen.

Kann jemand das erklären?

+0

Ich habe keine Ahnung, was 'hex2float' tut, da Sie nicht einmal die Bibliothek erwähnen, die Sie verwenden. Aber ich bin mir ziemlich sicher, dass es nicht 'int' s nimmt. –

+0

@EugeneSh .: 'hex2float's Definition ist im geposteten Code. – Dolda2000

+3

Oh. es verpasst. Strikte Alias-Verletzung –

Antwort

6

Die Erklärung für das beobachtete Verhalten ist, dass es durch den IEEE 754-2008 Gleitkommazahlen Standard vorgeschrieben ist:

7,4 Überlauf, wenn und

Die Überlaufausnahme signalisiert werden soll

Nur wenn die größte endliche Zahl des Zielformats um den Betrag überschritten wird, der das gerundete Gleitkommaergebnis gewesen wäre (siehe 4), wäre der Exponentenbereich unbegrenzt. Der Standardergebnis wird durch den Rundungsrichtungsattribut bestimmt werden und das Vorzeichen des Zwischenergebnisses wie folgt:

[...]

b) roundTowardZero führt alle Überläufe auf das Format des größten finite Zahl mit der Zeichen des Zwischenergebnisses.

Also für den Rundungsmodus hier (Abschneiden oder gegen Null Rundung) verwendet wird, ist das Ergebnis bei Überlauf die größte endliche Zahl, nicht Unendlichkeit.

+0

Danke! Ich habe das jetzt auch gerade gesehen ... –