Frage Wenn eine Float-Variable die Float-Grenzen verlässt, was passiert dann?


Ich habe zwei Dinge bemerkt:

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

  2. std::numeric_limits<float>::max()+(a large number mögen: 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?

Bearbeiten: Code zum Testen:

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;

13
2017-07-11 08:19


Ursprung


Antworten:


Formal ist das Verhalten nicht definiert. Auf einer Maschine mit IEEE Gleitkomma jedoch Überlauf nach dem Runden wird resultieren im Inf. 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 deutlich unter sehen FLT_MAX. Versuchen Sie etwas wie:

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

Das if wird ausgewertet werden truezumindest mit IEEE-Arithmetik. (Es gibt oder gab es zumindest Maschinen, wo float hat genug Präzision für die if zu bewerten false, aber sie sind nicht sehr häufig heute.)


10
2017-07-11 08:25



Es hängt davon ab, was Sie tun. Wenn der Float- "Überlauf" in einen Ausdruck kommt, der direkt zurückgegeben wird, d.h.

return std::numeric_limits::max() + std::numeric_limits::max();

Die Operation führt möglicherweise nicht zu einem Überlauf. Ich zitiere aus der C-Norm [ISO / IEC 9899: 2011]:

Die Rückgabeanweisung ist keine Zuweisung. Die Überlappungsbeschränkung von   Unterabschnitt 6.5.16.1 gilt nicht für den Fall der Funktionsrückgabe. Das   Die Darstellung von Fließkommawerten kann einen größeren Bereich haben oder   Präzision, als vom Typ impliziert wird; Ein Cast kann verwendet werden, um dies zu entfernen   extra Reichweite und Präzision.

Sehen Hier für mehr Details.


1
2017-07-11 08:27