quiet_NaN()

A

Alan Williams-Key

While debugging I discovered a variable had a value that I did not recognise
which led me to find out about numeric_limits. I inserted code to trap out
infinity, signaling_NaN and quiet_NaN but this didn't work because every
value was deemed to be equal to quiet_NaN. I cannot find any documentation
relating to this in the help files. Can anyone explain what quiet_NaN is and
why every value is deemed to be equal to it?
 
B

Ben Voigt [C++ MVP]

Alan Williams-Key said:
While debugging I discovered a variable had a value that I did not
recognise
which led me to find out about numeric_limits. I inserted code to trap out
infinity, signaling_NaN and quiet_NaN but this didn't work because every
value was deemed to be equal to quiet_NaN. I cannot find any documentation
relating to this in the help files. Can anyone explain what quiet_NaN is
and
why every value is deemed to be equal to it?

Are you sure you don't mean "no value is inequal to it"?

In algebra, two numbers are either equal or inequal. In IEEE arithmetic
which has NaNs, that's no longer true.

Specifically, if a or b is a NaN, then
(a != b) != !(a == b)
 
A

Alan Williams-Key

Ben Voigt said:
Are you sure you don't mean "no value is inequal to it"?

In algebra, two numbers are either equal or inequal. In IEEE arithmetic
which has NaNs, that's no longer true.

Specifically, if a or b is a NaN, then
(a != b) != !(a == b)
Ben,

Thanks for replying, but I don't follow your answer. (I'm sure you are right
but I only discovered the existence of NaN yesterday so a little more
explanation would be appreciated.) Here is the code I wrote:
double Heading360(double head)
{
if (head == numeric_limits<double>::infinity())
return 0;
if (head == numeric_limits<double>::quiet_NaN())
return 0;
if (head == numeric_limits<double>::signaling_NaN())
return 0;
// function code...not relevant here
return someOtherValue;
}

No matter what the input value was (normal values, that is) the second
return 0 was always taken. When I commented out the second test and return
statement, normal values did not take either of the remaining return 0;
routes.

So, are you saying I should have coded this as

if (!(head != numeric_limits<double>::quiet_NaN()))
return 0;
?

Also, what is the difference between quiet_NaN and signaling_NaN (and I
wouldn't have to be asking these questions if the help files had the answer).
Alan
 
A

Alan Williams-Key

Alan Williams-Key said:
Ben,

Thanks for replying, but I don't follow your answer. (I'm sure you are right
but I only discovered the existence of NaN yesterday so a little more
explanation would be appreciated.) Here is the code I wrote:
double Heading360(double head)
{
if (head == numeric_limits<double>::infinity())
return 0;
if (head == numeric_limits<double>::quiet_NaN())
return 0;
if (head == numeric_limits<double>::signaling_NaN())
return 0;
// function code...not relevant here
return someOtherValue;
}

No matter what the input value was (normal values, that is) the second
return 0 was always taken. When I commented out the second test and return
statement, normal values did not take either of the remaining return 0;
routes.

So, are you saying I should have coded this as

if (!(head != numeric_limits<double>::quiet_NaN()))
return 0;
?

Also, what is the difference between quiet_NaN and signaling_NaN (and I
wouldn't have to be asking these questions if the help files had the answer).
Alan

It's OK I think I've got it.
if (heading != heading)
return 0;
This returns if heading is a NaN, yes?
 
B

Ben Voigt [C++ MVP]

It's OK I think I've got it.
if (heading != heading)
return 0;
This returns if heading is a NaN, yes?

It should, yes. But why not just use _finite ?

http://msdn.microsoft.com/en-us/library/sb8es7a8(VS.80).aspx

The difference between quiet NaN values (there's more than one) and
signalling NaN values is that signalling NaN values produce an error if FPU
exceptions are enabled (similar to divide by zero). Under Windows that
would map to a structured exception handler aka SEH.

For more detailed information, there another function _fpclass
http://msdn.microsoft.com/en-us/library/39s1cck2(VS.80).aspx

The problem with all these functions is that they use the C data type
'double' which passes the argument in an FPU register, so they can't be used
to test for signalling NaNs when FPU exceptions are enabled. If you are for
example performing sanity checks on binary data read from a file, you have
to do integer bit tests and only reinterpret_cast to double after you're
done with the sanity checks. The different bit patterns are described here:
http://en.wikipedia.org/wiki/IEEE_754
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top