jeudi 16 avril 2020

NAN Differences - std::nan vs quiet_NaN() vs Macro NAN

I was wondering what the differences between the following types of nan were. Except for the visual difference of NAN_macro (which evaluates to -nan(ind) as opposed to just nan), they all seem to behave the same (as per the sample script below).

I had a look at some other answers, e.g. What is difference between quiet NaN and signaling NaN?. But I still don't quite understand why NAN is -nan(ind) whereas std::numeric_limits<double>::quiet_NaN() is nan, or why we have std::nan("") and std::nan("1") if at the end of the day they both seem to be the same concept.

Any explanations or clarifying links would be great.

#include <cmath>
#include <limits>

int main()
{
    using num_lim = std::numeric_limits<double>;

    const double NAN_macro   = static_cast<double>(NAN);  // -nan(ind)
    const double NAN_quiet   = num_lim::quiet_NaN();      // nan
    const double NAN_sig     = num_lim::signaling_NaN();  // nan
    const double NAN_str     = std::nan("");              // nan
    const double NAN_str1    = std::nan("1");             // nan
    const double NAN_strLong = std::nan("some string");   // nan

    const bool isnan_macro   = std::isnan(NAN_macro);    // true
    const bool isnan_quiet   = std::isnan(NAN_quiet);    // true
    const bool isnan_sig     = std::isnan(NAN_sig);      // true
    const bool isnan_str     = std::isnan(NAN_str);      // true
    const bool isnan_str1    = std::isnan(NAN_str1);     // true
    const bool isnan_strLong = std::isnan(NAN_strLong);  // true

    const bool not_equal_macro   = (NAN_macro   != NAN_macro);   // true
    const bool not_equal_quiet   = (NAN_quiet   != NAN_quiet);   // true
    const bool not_equal_sig     = (NAN_sig     != NAN_sig);     // true
    const bool not_equal_str     = (NAN_str     != NAN_str);     // true
    const bool not_equal_str1    = (NAN_str1    != NAN_str1);    // true
    const bool not_equal_strLong = (NAN_strLong != NAN_strLong); // true

    const double sum_macro   = 123.456 + NAN_macro;    // -nan(ind)
    const double sum_quiet   = 123.456 + NAN_quiet;    // nan
    const double sum_sig     = 123.456 + NAN_sig;      // nan
    const double sum_str     = 123.456 + NAN_str;      // nan
    const double sum_str1    = 123.456 + NAN_str1;     // nan
    const double sum_strLong = 123.456 + NAN_strLong;  // nan
}

Aucun commentaire:

Enregistrer un commentaire