Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does C++ deal with NAN? Is there a standard way or is compiler dependent?

In a program that needs to process sin(x)/x function, I encountered NAN problem, I simplified the problem in the following code:

#include <iostream>
#include <cmath>

int main()
{
    std::cout.precision(15);

    //This line compiles and run in g++, but does not compile in Visual Studio 2013
    std::cout << 0.0/0.0 << std::endl;

    //This line compiles and run in both g++ and VS2013
    std::cout << std::sin(0.0)/0.0 << std::endl;

    return 0;
}

In g++, the output is: -nan -nan, in VS2013, the output is: -1.IND, because the first line does not compile so I commented it out.

My questions are:

  1. What does this '-1.IND' mean?

  2. It seems NAN processing is compiler dependent, should this be standardized in C++? Why?

  3. I used this hack to deal with this problem:

    double sinc(double x)
    {
        if(x == 0.0)
            return 1.0;
        return std::sin(x)/x;
    }
    

Is this the right way?

EDIT: another question, 4. why VS2013 deal with 0.0/0.0 and sin(0.0)/0.0 differently?

like image 849
dguan Avatar asked Jul 29 '14 11:07

dguan


People also ask

What is NaN in C programming?

NaN, an acronym for Not a Number is an exception that usually occurs in the cases when an expression results in a number that is undefined or can't be represented. It is used for floating-point operations. For example: The square root of negative numbers.

Does C have NaN?

In C99, the C header <math. h> defines nan() , nanf() , and nanl() that return different representations of NaN (as a double , float , and int respectively), and infinity (if avaliable) could be returned by generating one with log(0) or something.

What is NaN in double C?

Overview. In C#, the Double. NaN field represents a value that is not a number.

What is INF in C?

You can also type them directly into an expression or Edit table. Inf means infinity, and is the result of dividing a positive number by zero -- e.g., 1/0 → Inf. or computing a number larger than 1.796E308 (the largest number that your computer can represent in 64 bits) -- e.g. 1E307 * 100 → Inf.


2 Answers

There are similar questions to yours answered on SO:

1.What does this '-1.IND' mean?

See What do 1.#INF00, -1.#IND00 and -1.#IND mean?

2.It seems NAN processing is compiler dependent, should this be standardized in C++? Why?

See A few things about division by zero in C (it says C, but it talks about C++)

3.I used this hack to deal with this problem:

double sinc(double x) {

    if(x == 0.0)
        return 1.0;
    return std::sin(x)/x; 
}

Is this the right way?

Yes, this implementation of the sinc function will work and (Thanks to @MSalters for the comment) is mathematically correct; however, keep in mind that, while it will work for this case, don't make a habit of comparing double types with ==.

like image 178
nasser-sh Avatar answered Nov 09 '22 20:11

nasser-sh


To add an answer for (4), sin(x) is a runtime function, and thus sin(0.0)/0.0 is handled as an expression which is evaluated at runtime. OTOH, 0.0/0.0 is handled fully by the compiler, which is why it spots the problem. An implementation detail of your Visual Studio version, and not something on which you can count.

like image 20
MSalters Avatar answered Nov 09 '22 22:11

MSalters