float & double: infinity & NaN
-
Hiho!
floats und doubles haben ja spezielle Werte fuer +- Unendlich sowie - laut http://www.gnu.org/software/libc/manual/html_node/Infinity-and-NaN.html zumindest auf speziellen Maschinen - auch einen eigenen "Not a Number" Wert.
Laut folgendem Testprogramm:#include <cmath> #include <iostream> using namespace std; int main() { cout << "NaN:\t" << sqrt(-1) << '\n'; cout << "+inf:\t" << 1.0/0.0 << '\n'; cout << "-inf:\t" << log(0) << '\n'; }Gibts auf meiner Maschine keinen eigenen NaN-Wert:
NaN: -1.#IND +inf: 1.#INF -inf: -1.#INFGibts in C++ einen standardisierten Weg, einer float- oder double-Variable einen solchen Wert zuzuweisen? Die im obigen Link beschriebenen Makros gibts ja anscheinend erst ab C99.
-
Schau dir mal die Template-Klasse 'numeric_limits<>' an - die kannst du unter anderem nach Unendlich (numeric_limits<T>::infinity()) und NaN-Werten (quiet_NaN() bzw. signalling_NaN()) fragen.
-
Blue-Tiger schrieb:
Hiho!
floats und doubles haben ja spezielle Werte fuer +- Unendlich sowie - laut http://www.gnu.org/software/libc/manual/html_node/Infinity-and-NaN.html zumindest auf speziellen Maschinen - auch einen eigenen "Not a Number" Wert.
Laut folgendem Testprogramm:#include <cmath> #include <iostream> using namespace std; int main() { cout << "NaN:\t" << sqrt(-1) << '\n'; cout << "+inf:\t" << 1.0/0.0 << '\n'; cout << "-inf:\t" << log(0) << '\n'; }Gibts auf meiner Maschine keinen eigenen NaN-Wert:
NaN: -1.#IND +inf: 1.#INF -inf: -1.#INFGibts in C++ einen standardisierten Weg, einer float- oder double-Variable einen solchen Wert zuzuweisen? Die im obigen Link beschriebenen Makros gibts ja anscheinend erst ab C99.
-1.#IND (steht für indefinite) ist auch ein NaN - typischerweise das Einzige, das unmittelbar als Ergebnis einer Rechenoperation enstehen kann - alle anderen NaNs muss man durch Bit-Manipulation künstlich erschaffen.
-
thx

-
template<typename T> inline T getNegativeInfinity() { UBSYSTEM_STATIC_ASSERT(std::numeric_limits<T>::has_infinity); return -std::numeric_limits<T>::infinity(); } /*=======================================================*/ //double x = UbMath::getPositiveInfinity<double>(); template<typename T> inline T getPositiveInfinity() { UBSYSTEM_STATIC_ASSERT(std::numeric_limits<T>::has_infinity); return std::numeric_limits<T>::infinity(); } /*=======================================================*/ //double x; bool b = UbMath::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; } /*=======================================================*/ //double x = UbMath::getNaN<double>(x); template<typename T> inline T getNaN() { UBSYSTEM_STATIC_ASSERT(std::numeric_limits<T>::has_quiet_NaN); return std::numeric_limits<T>::quiet_NaN(); } /*=======================================================*/ //double x; bool b = UbMath::isNaN(x); template<typename T> inline bool isNaN(const T& x) { UBSYSTEM_STATIC_ASSERT(std::numeric_limits<T>::has_quiet_NaN); return std::numeric_limits<T>::has_quiet_NaN && (x != x); }mit:
#define UBSYSTEM_STATIC_ASSERT(x) static_cast<void>(sizeof(UbSystem::static_assert<x>));und
template<bool> struct static_assert; //deklaration template<> struct static_assert<true>{}; //deklaration + definition der spezialisierung fuer "true" //static_assert<false> führt zu compiler fehler, da dafür //keine implementierung vorhanden! //UBSYSTEM_STATIC_ASSERT(false)