Frage

In meinen Programmen Unendlichkeit entsteht in der Regel, wenn ein Wert von Null geteilt wird. Ich unbestimmt, wenn ich Null durch Null teilen. Wie überprüfen Sie für unendliche und unbestimmte Werte in C ++?

In C ++, Unendlichkeit wird durch 1. # INF vertreten. Unbestimmte wird dargestellt durch -1. # IND. Das Problem ist, wie man testen, ob eine Variable unendlich oder unbestimmt ist. Unendlich Überprüfung ist relativ einfach: Sie können die Unendlichkeit Definition in Ihrem speziellen C ++ finden. Für meinen Fall (VS2003), es ist std :: numeric_limits :: unendlich (). Sie müssen „Grenzen“ enthalten, um es zu benutzen. Sie können diesen unendlichen Wert einer Variablen zuweisen und Sie können es bis zu einem gewissen Wert vergleichen, um zu überprüfen, ob dieser Wert unendlich ist.

Unbestimmte ist ein wenig schwierig, weil man nicht einen unbestimmten Wert auf einen anderen Wert vergleichen. Jeder Vergleich gibt false zurück. Sie können diese Eigenschaft verwenden, um einen unbestimmten Wert zu erfassen, indem sie sich selbst zu vergleichen. Angenommen, Sie haben eine doppelte variable aVal genannt haben. Unter normalen Bedingungen gibt aVal! = AVal false. Aber wenn der Wert unbestimmt ist, aIndVal! = AIndVal gibt true zurück. Diese seltsame Situation für unendliche Werte nicht vorhanden ist, das heißt aInfVal! = AInfVal immer false zurück.

Hier sind zwei Funktionen, die verwendet werden können, für unbestimmte und unendliche Werte zu prüfen:

#include "limits.h"
#include "math.h"

bool isIndeterminate(const double pV)
{
    return (pV != pV);
} 

bool isInfinite(const double pV)
{
    return (fabs(pV) == std::numeric_limits::infinity())
}

Gibt es bessere Möglichkeiten für diese Kontrollen, bin ich etwas fehlt?

War es hilfreich?

Lösung

Für Visual Studio würde ich verwenden _isnan und _finite oder vielleicht _fpclass .

Aber wenn Sie haben Zugang zu einer C ++ 11-Lage-Standardbibliothek und Compiler Sie std::isnan und std::isinf .

Andere Tipps

Obwohl C ++ 03 bietet keine C99 isnan und isinf Makros , C ++ 11 standardisiert sie von ihnen als Funktionen bieten. Wenn Sie C ++ 11, statt streng C ++ 03 verwenden können, dann würden diese Reiniger Optionen sein, die von Makros zu vermeiden, Compiler Einbauten und plattformabhängige Funktionen.

C ++ 11 std::isfinite Renditen true für alle Werte außer inf und nan; so !isfinite sollte für unendliche und unbestimmte Werte in einem Schuss überprüfen.

Obwohl nicht unbedingt ein Teil von C ++ 03, wenn Ihr Compiler einige der neuen C99 Features des Standard bietet Header-Datei, dann können Sie den Zugriff auf folgenden „Funktionsmakros“ haben: isfinite, isinf, isnan. Wenn ja, wäre dies die einfachste und sicherste Weg, um diese Kontrollen durchzuführen.

Sie können auch diese als strenge C ++ verwenden - einzige Lösung. Sie bieten nicht wirklich mehr als die Lösung des OP außer zusätzliche Sicherheit durch die Verwendung von Typ Zügen und vielleicht den kleinsten Geschwindigkeitsschub im Fall von is_inf.

template <bool> struct static_assert;
template <> struct static_assert<true> { };

template<typename T>
inline bool is_NaN(T const& x) {
    static_cast<void>(sizeof(static_assert<std::numeric_limits<T>::has_quiet_NaN>));
    return std::numeric_limits<T>::has_quiet_NaN and (x != x);
}

template <typename T>
inline bool is_inf(T const& x) {
    static_cast<void>(sizeof(static_assert<std::numeric_limits<T>::has_infinity>));
    return x == std::numeric_limits<T>::infinity() or x == -std::numeric_limits<T>::infinity();
}

(Vorsicht selbstgemachter static_assert)

Es gibt isfinite von C99 oder POSIX oder etwas, was ich denke.

Ein hackish Weg, es zu tun ist, x-x == 0 zu testen; wenn x unendlich oder NaN ist, dann x-x ist NaN so der Vergleich fehlschlägt, während, wenn x endlich ist, dann x-x 0 ist und der Vergleich erfolgreich ist. Ich würde empfehlen, isfinite verwenden, obwohl, oder die Verpackung diesen Test in eine Funktion / Makro etwas wie isfinite genannt, so dass Sie es loswerden kann alles, wenn die Zeit kommt.

if (x!=x)              ... then x is nan
if (x>0 && x/x != x/x) ... then x is +inf
if (x<0 && x/x != x/x) ... then x is -inf

Dies könnte funktionieren auch (aber beinhaltet nennen exp () und Gleichheit der Doppel Prüfung):

if (exp(-x)==0.) ... then x is inf
if (exp(x)==0.)  ... then x is -inf
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top