2008-12-07 14 views
55

Ich bin mit einigen C-Code mit Floats rum, und ich bekomme 1. # INF00, -1. # IND00 und -1. # IND, wenn ich versuche, Schwimmer auf dem Bildschirm zu drucken. Was bedeuten diese Werte?Was bedeuten 1. # INF00, -1. # IND00 und -1. # IND?

Ich glaube, dass 1. # INF00 bedeutet positive Unendlichkeit, aber was ist mit -1. # IND00 und -1. # IND? Ich habe auch manchmal diesen Wert gesehen: 1. $ NaN was keine Zahl ist, aber was verursacht diese seltsamen Werte und wie können mir diese bei der Fehlersuche helfen?

Ich verwende MinGW die ich glaube, IEEE 754 Darstellung für Float Point-Nummern verwendet.

Kann jemand all diese ungültigen Werte auflisten und was sie bedeuten?

Antwort

61

Von IEEE floating-point exceptions in C++:

This page will answer the following questions.

  • My program just printed out 1.#IND or 1.#INF (on Windows) or nan or inf (on Linux). What happened?
  • How can I tell if a number is really a number and not a NaN or an infinity?
  • How can I find out more details at runtime about kinds of NaNs and infinities?
  • Do you have any sample code to show how this works?
  • Where can I learn more?

These questions have to do with floating point exceptions. If you get some strange non-numeric output where you're expecting a number, you've either exceeded the finite limits of floating point arithmetic or you've asked for some result that is undefined. To keep things simple, I'll stick to working with the double floating point type. Similar remarks hold for float types.

Debugging 1.#IND, 1.#INF, nan, and inf

If your operation would generate a larger positive number than could be stored in a double, the operation will return 1.#INF on Windows or inf on Linux. Similarly your code will return -1.#INF or -inf if the result would be a negative number too large to store in a double. Dividing a positive number by zero produces a positive infinity and dividing a negative number by zero produces a negative infinity. Example code at the end of this page will demonstrate some operations that produce infinities.

Some operations don't make mathematical sense, such as taking the square root of a negative number. (Yes, this operation makes sense in the context of complex numbers, but a double represents a real number and so there is no double to represent the result.) The same is true for logarithms of negative numbers. Both sqrt(-1.0) and log(-1.0) would return a NaN, the generic term for a "number" that is "not a number". Windows displays a NaN as -1.#IND ("IND" for "indeterminate") while Linux displays nan. Other operations that would return a NaN include 0/0, 0*∞, and ∞/∞. See the sample code below for examples.

In short, if you get 1.#INF or inf, look for overflow or division by zero. If you get 1.#IND or nan, look for illegal operations. Maybe you simply have a bug. If it's more subtle and you have something that is difficult to compute, see Avoiding Overflow, Underflow, and Loss of Precision. That article gives tricks for computing results that have intermediate steps overflow if computed directly.

+3

Ich weiß, dass das OP nicht wirklich danach gefragt hat, aber als ein praktischer Test wird 'myfloat == myfloat' false zurückgeben, wenn Sie einen dieser magischen Werte haben. – tenpn

+7

@tenpn Eigentlich in C++, + Unendlichkeit == + Unendlichkeit. Versuchen Sie es mit 1.0/0.0: '1. # INF00' ==' 1. # INF00' gibt wahr zurück, '-1. # INF00' ==' -1. # INF00' gibt wahr zurück, aber '1. # INF00' = = '-1. # INF00' ist falsch. – bobobobo

+2

Nicht sicher über andere Konfigurationen, aber unter Windows 7/Visual Studio 2010. float nan = sqrtf (-1.0f); Nan == Nan; // ergibt wahr ... im Gegensatz zu dem, was tenpn sagte .. (Kommentar von Yevgen V) – Jeff

3

Für die von Ihnen in einer .NET-Umgebung der folgenden eine praktische Möglichkeit, seine nicht-Zahlen heraus zu filtern (in diesem Beispiel ist in VB.NET, aber es ist wahrscheinlich ähnlich in C#):

If Double.IsNaN(MyVariableName) Then 
    MyVariableName = 0 ' Or whatever you want to do here to "correct" the situation 
End If 

Wenn Sie versuchen, eine Variable zu verwenden, die einen NaN-Wert hat, werden Sie die folgende Fehlermeldung erhalten:

Value was either too large or too small for a Decimal.

+3

Dies wird nicht erkannt 1. INF. Sie müssen auch 'Double.IsInfinity (MyVariableName)' verwenden, um nach +/- unendlich zu suchen. – user1318499

2

Ihre Frage "Was sind sie?" Ist bereits oben beantwortet.

Soweit das Debuggen (Ihre zweite Frage), obwohl und Bibliotheken in der Entwicklung, wo Sie für spezielle Eingabewerte überprüfen möchten, können Sie die folgenden Funktionen, die in Windows-C finden ++:

_isNaN(), _isfinite () und _fpclass()

Unter Linux/Unix sollten Sie isnan(), isfinite(), isnormal(), isinf(), fpclassify() nützlich finden (und möglicherweise müssen Sie mit libm mithilfe des Compilers verknüpfen) Flagge -lm).

Verwandte Themen