c++ - How to have all platform compiler output the same string for NaN? -


consider code snippet:

#include <iostream> #include <string> #include <limits>  int main() {     std::cout << std::numeric_limits<double>::quiet_nan(); } 

when compiled visual studio 2010, output 1.#qnan. when compiled g++, output nan. note visual studio 2015 outputs "nan".

however, need both produce same output. what's simple way that? tried override operator<< double feel that's not right way do. can string used nan value forced @ stream level, or better, @ global level (using std::locale stuff?...never used that...).

i found squaring_num_put example. interesting because it's way modify number redirected output. i'm having hard time trying adapt problem (could not make do_put send either number or hard coded "nan" string ostream...).

you might use stream manipulator or modify underlying locale:

manipulator:

#include <cmath> #include <ostream>  template <typename t> struct floatformat {     const t value;      floatformat(const t& value)     : value(value)     {}      void write(std::ostream& stream) const {         if(std::isnan(value))             stream << "not number";         else             stream << value;     } };  template <typename t> inline floatformat<t> float_format(const t& value) {     return floatformat<t>(value); }  template <typename t> inline std::ostream& operator << (std::ostream& stream, const floatformat<t>& value) {     value.write(stream);     return stream; }  int main() {     std::cout << float_format(std::numeric_limits<double>::quiet_nan()) << '\n';  } 

locale:

#include <cmath> #include <locale> #include <ostream>  template<typename iterator = std::ostreambuf_iterator<char>> class numput : public std::num_put<char, iterator> {     private:     using base_type = std::num_put<char, iterator>;      public:     using char_type = typename base_type::char_type;     using iter_type = typename base_type::iter_type;      numput(std::size_t refs = 0)     :   base_type(refs)     {}      protected:     virtual iter_type do_put(iter_type out, std::ios_base& str, char_type fill, double v) const override {         if(std::isnan(v))             out = std::copy(std::begin(notanumber), std::end(notanumber), out);         else             out = base_type::do_put(out, str, fill, v);         return out;     }      virtual iter_type do_put(iter_type out, std::ios_base& str, char_type fill, long double v) const override {         if(std::isnan(v))             out = std::copy(std::begin(notanumber), std::end(notanumber), out);         else             out = base_type::do_put(out, str, fill, v);         return out;     }      private:     static const char notanumber[]; };  template<typename iterator> const char numput<iterator>::notanumber[] = "not number";  #include <iostream> #include <limits>  int main() {     #if 1     {         const std::size_t nodestroy = 1;         numput<> num_put(nodestroy);         std::locale locale(std::cout.getloc(), &num_put);         std::locale restore_locale = std::cin.getloc();         std::cout.imbue(locale);         std::cout << std::numeric_limits<double>::quiet_nan() << '\n';         // num_put facet going out of scope:         std::cout.imbue(restore_locale);     }     #else     {         // alternitvely use reference counted facet , pass ownership locales:         auto num_put = new numput<>();         std::locale locale(std::cout.getloc(), num_put);         std::cout.imbue(locale);         std::cout << std::numeric_limits<double>::quiet_nan() << '\n';     }     #endif     std::cout << std::numeric_limits<double>::quiet_nan() << '\n'; } 

Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -