Unendlich in float variable abfragen [erledigt]
-
Ich bin grade dabei ein 3D graph Zeicher zu schreiben, allerdings kann es vorkommen, dass in meinem Array an floatwerten ∞ sind, wie kann ich diese abfragen? Ich will nicht, dass Mein Programm versucht diese zu Zeichnen, da kommt nur müll raus.
Hier ist ein auszug, wie ein Array nach der Berechnung der Gleichung z(x,y)=1/x+1/y aussieht:
-0.40 -0.45 -0.53 -0.70 -1.20 inf 0.80 0.30 0.13 0.05 -0.45 -0.50 -0.58 -0.75 -1.25 inf 0.75 0.25 0.08 0.00 -0.53 -0.58 -0.67 -0.83 -1.33 inf 0.67 0.17 0.00 -0.08 -0.70 -0.75 -0.83 -1.00 -1.50 inf 0.50 0.00 -0.17 -0.25 -1.20 -1.25 -1.33 -1.50 -2.00 inf 0.00 -0.50 -0.67 -0.75 inf inf inf inf inf inf inf inf inf inf 0.80 0.75 0.67 0.50 0.00 inf 2.00 1.50 1.33 1.25 0.30 0.25 0.17 0.00 -0.50 inf 1.50 1.00 0.83 0.75 0.13 0.08 0.00 -0.17 -0.67 inf 1.33 0.83 0.67 0.58 0.05 0.00 -0.08 -0.25 -0.75 inf 1.25 0.75 0.58 0.50
-
#include <limits> std::numeric_limits<float>::infinity()
ist, was du suchst.
-
musst allerdinsg drauf achten, ob es sich um pos oder negative unendlichkeit handelt...
wir haben und die methoden boost-mäßig gewrapped:#include <cassert> #include <limits> template<typename T> inline T getNegativeInfinity() { assert(std::numeric_limits<T>::has_infinity); return -std::numeric_limits<T>::infinity(); } /*=======================================================*/ //double x = getPositiveInfinity<double>(); template<typename T> inline T getPositiveInfinity() { assert(std::numeric_limits<T>::has_infinity); return std::numeric_limits<T>::infinity(); } /*=======================================================*/ //double x; bool b = isInfinity(x); template<typename T> inline bool isInfinity(const T& value) { if(value==getNegativeInfinity<T>()) return true; if(value==getPositiveInfinity<T>()) return true; return false; }
-
muffmolch schrieb:
assert(std::numeric_limits<T>::has_infinity);
Wäre da nicht BOOST_STATIC_ASSERT sinnvoller?
-
jaja, wären sie. aber teile unseres projektes sind unabhängig von boost, weil boost auf diversen vector rechnern (z.B. NEC SX6) seeeehr mühseelig zu compilieren ist, da dort nur compiler-eigenentwicklungen vorliegen, die quasi nur vollen support von FORTRAN und C haben. C++ ist dort meist alles andere auls 100% std-konform
aber das assert greift bei uns eh nur im debug modus...
-
muffmolch schrieb:
jaja, wären sie. aber teile unseres projektes sind unabhängig von boost, weil boost auf diversen vector rechnern (z.B. NEC SX6) seeeehr mühseelig zu compilieren ist, da dort nur compiler-eigenentwicklungen vorliegen, die quasi nur vollen support von FORTRAN und C haben. C++ ist dort meist alles andere auls 100% std-konform
So ein STATIC_ASSERT kann man sich auch selber basteln.
-
muffmolch schrieb:
musst allerdinsg drauf achten, ob es sich um pos oder negative unendlichkeit handelt...
wir haben und die methoden boost-mäßig gewrapped:#include <cassert> #include <limits> template<typename T> inline T getNegativeInfinity() { assert(std::numeric_limits<T>::has_infinity); return -std::numeric_limits<T>::infinity(); } /*=======================================================*/ //double x = getPositiveInfinity<double>(); template<typename T> inline T getPositiveInfinity() { assert(std::numeric_limits<T>::has_infinity); return std::numeric_limits<T>::infinity(); } /*=======================================================*/ //double x; bool b = isInfinity(x); template<typename T> inline bool isInfinity(const T& value) { if(value==getNegativeInfinity<T>()) return true; if(value==getPositiveInfinity<T>()) return true; return false; }
naja, eigentlich möchte ich alle +∞ -∞ und nan (Not a Number) gleich behandeln, denn schließlich kann ich sie ja alle nicht anzeigen. Sie entstehen bei der division durch 0, da ist sowiso nicht definiert was rauskommt, das kann im prinziep alles sein.
ja und wie funktionier das BOOST_STATIC_ASSERT?
-
Dazu benutzt man ein Template ohne Definition und eine Spezialisierung für true (mit leerer Definition), wenn man das ganze in einem Ausdruck (sizeof bietet sich ideal an) verwendet, kann es nur compiliert werden, wenn das Objekt auch erstellt werden konnte, was nur der Fall ist, wenn das Templateargument true übergeben bekommt:
template<bool> struct static_assert; template<> struct static_assert<true>{}; #define STATIC_ASSERT(x) sizeof(static_assert<x>) // oder kürzer: #define STATIC_ASSERT(x) static_assert<x>() STATIC_ASSERT(true); // OK STATIC_ASSERT(false); // Fehler zur Compilezeit
Greetz
-
isnan, finite ?
Sind doch Funktionen in float.h
-
fine schrieb:
isnan, finite ?
Sind doch Funktionen in float.hDas ist doch C99, wenn ich mich richtig entsinne.
Allerdings ist ein Vergleich auf Gleichheit mit ...::infinity/nan nicht zulässig, da es sich z.B. um Signalling NaNs handeln kann, die das Programm sofort abrauchen lassen. Auf die AFAIK einzig verlässliche Variante mit isnan und konsorten musst du wohl auf den neuen C++ Standard warten, der die C99 Teile integriert. Ansonsten wird das Programm kaum portabel.
-
Am einfachsten ist es, wenn du in deiner Gleichung z(x,y)=1/x+1/y
x und y erst gar nicht Null werden lässt, dann kann für z auch nicht unendlich rauskommen.Oder aber, wenn z == (+/-) inf wird, dann gar nicht erst in die Funktion zum Zeichnen schicken.
Ich würde die erste Lösung vorziehen, dann sparst du dir finite, oder eine eventuell selbstgeschriebene Funktion aufzurufen, die hoffnungslos vertemplatetisiert ist.
Zu NaN kommt es in dieser Gleichung nicht.
MfG
-
garnich erst ∞ werden lassen, halte ich für nicht möglich, was soll ich denn sonst in mein array eintragen, wenn nicht ∞? Wenn ich in mein array nicht Reelle Zahlen wie ∞ eintragen kann, dann hat das für mich den Vorteil, dass ich diese dann abfangen kann, wenn ich sie Zeichne, würde ich das vorher Abfangen, dann müsste ich mich zusätzlich eine Map anlegen, in der Gespeichert wird, ob der Wert überhaupt Darstellbar ist.
if (finite(grid[i][j]))
erfüllt meine anforderungen zu 100%, und ist schön kurz, egal ob das jetzt C ist oder nicht.