2013-07-11 7 views
13

bemerkte ich zwei Dinge:Wenn eine Float-Variable die Float-Grenzen verlässt, was passiert?

  1. std::numeric_limits<float>::max()+(a small number)gibt:std::numeric_limits<float>::max().

  2. std::numeric_limits<float>::max()+(a large number wie: std::numeric_limits<float>::max()/3)gibt inf.

Warum dieser Unterschied? Führt 1 oder 2 zu einem OVERFLOW und damit zu einem undefinierten Verhalten?

Edit:-Code für diese Prüfung:

1.

float d = std::numeric_limits<float>::max(); 
float q = d + 100; 
cout << "q: " << q << endl; 

2.

float d = std::numeric_limits<float>::max(); 
float q = d + (d/3); 
cout << "q: " << q << endl; 
+1

können Sie bitte den Code angeben, mit dem Sie das Verhalten 1 und 2 "abgeleitet" haben? –

+1

Intuitiv: float kann 7 signifikante Ziffern speichern. Das Hinzufügen einer kleinen Zahl zu 3.4E38 fügt also nicht genügend Ziffern hinzu, um einen Unterschied zu machen. Sie müssen mindestens ~ 3.4E31 hinzufügen. –

+0

Hier ist der Code: 1- float d = std :: numerische_grenzen :: max(); float q = d + 100; cout << "q:" << q << endl; 2- Gleitkomma d = std :: numeric_limits :: max(); float q = d + (d/3); cout << "q:" << q << endl; – WildThing

Antwort

10

Formal ist das Verhalten nicht definiert. Bei einer Maschine mit IEEE Gleitkomma wird jedoch der Überlauf nach der Rundung in Inf ergeben. Die Genauigkeit ist jedoch begrenzt und die Ergebnisse nach der Rundung von FLT_MAX + 1 sind FLT_MAX.

Sie können den gleichen Effekt mit Werten gut unter FLT_MAX sehen. Versuchen Sie so etwas wie:

float f1 = 1e20;  // less than FLT_MAX 
float f2 = f1 + 1.0; 
if (f1 == f2) ... 

Die if zu true bewerten, zumindest mit IEEE-Arithmetik. (Es existieren oder zumindest bestanden haben, Maschinen, bei denen float zu genug Präzision für die if zu bewerten hat false, aber sie sind nicht sehr verbreitet heute.)

+0

Kann ich das Ergebnis von (FLT_MAX + etwas Positives) in weiteren Operationen oder Tests ohne Probleme verwenden (undefiniertes Verhalten)? – WildThing

+1

@ user2114690 Vielleicht. Wenn Sie "Inf" erhalten, wird dies weitergegeben, und Sie können am Ende nachsehen. Wenn Sie 'FLT_MAX' kleine Werte hinzufügen (und' FLT_MAX' erhalten), ist wahrscheinlich etwas mit Ihrem Algorithmus nicht in Ordnung. Es wird kein undefiniertes Verhalten geben, aber es besteht eine sehr gute Chance, dass Ihre Ergebnisse falsch sind. –

+0

Wie kann man wissen, ob eine Maschine einen IEEE Fließkomma verwendet? – WildThing

1

Es hängt davon ab, was Sie tun. Wenn der Float- "Überlauf" in einen Ausdruck kommt, der direkt zurückgegeben wird, d. H. Der Vorgang führt möglicherweise nicht zu einem Überlauf. Ich zitiere aus der C-Norm [ISO/IEC 9899: 2011]:

Die Rückgabeanweisung ist keine Aufgabe. Die Überlappungsbeschränkung von Abschnitt 6.5.16.1 gilt nicht für den Fall der Funktionsrückgabe. Die Darstellung von Fließkommawerten kann einen größeren Bereich haben oder Genauigkeit als vom Typ impliziert; Ein Guss kann verwendet werden, um diese zusätzliche Reichweite und Präzision zu entfernen.

Weitere Informationen finden Sie unter here.

+1

Das ist ein ganz anderes Problem , Maschinen werden die Arithmetik in doppelter Genauigkeit oder mehr ausführen, und die meisten Compiler geben den Wert in einem Register mit "doppelter" Genauigkeit oder mehr zurück. Dies kann zu einigen überraschenden Ergebnissen führen, aber es ist nicht das Problem, über das er sich beschwert. (Ob dies legal ist C++ ist sehr umstritten --- ich glaube nicht, dass es ist. Aber es _ist_ was Compiler tun.) –

+0

Dies ist in der Tat erlaubt durch den Standard.Sie haben Recht, dies kann zu einigen (sehr) überraschend führen Ergebnisse wie die in der obigen Referenz zitiert –

+0

Sie zitiert den C-Standard.In C++, ist die Rückgabe eines Werts als Initialisierung einer Variablen des angegebenen Typs mit Kopie Initialisierung (siehe § 8.5/14). Wenn an anderer Stelle kein Text vorliegt, der eine explizite Ausnahme macht, bedeutet dies, dass der Rückgabewert "so als ob" eine "float" Variable initialisiert sein und dann gelesen werden muss. (Nicht, dass dies in der Praxis einen Unterschied macht, , da Compiler es nicht respektieren.) –

Verwandte Themen