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.#INF
    

    Gibts 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.


  • Mod

    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.#INF
    

    Gibts 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)
    

Anmelden zum Antworten