I have g++ 4.4.3 on Linux with Ubuntu Lucid Lynx, and I am getting a:
-nan
as a result. On Hardy Heron with g++ 4.3.1, I am getting all
nan
This is causing my text diff regression to fail, since I am using cout to print this numerical result.
What is the meaning of a signed nan, and is there a way to tell the compiler that an unsigned nan is sufficient?
There is no notion of a "negative NaN" in IEEE-754 arithmetic. The NaN encoding still has a sign bit, and there is a notion of a "sign bit" operation which uses or affects this bit (copysign, abs, a few others), but it does not have any meaning when the NaN encoding is interpreted as a value.
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.
To check whether a floating point or double number is NaN (Not a Number) in C++, we can use the isnan() function. The isnan() function is present into the cmath library. This function is introduced in C++ version 11.
The change in behaviour may be due to libraries rather than the compiler. There is certainly a change in glibc around the right sort of time - from the entry for 2009-08-23 at line 2528 in ChangeLog.17
in the glibc source:
...
* stdio-common/printf_fp.c: ISO C expects to print the sign of NaN
as well.
...
You can get a signed NaN since the NaN-ness of the value and the sign of the value are controlled by different bits in IEEE754 (NaN is simply indicated by special exponent values, distinct from the sign bit). I'm at a loss as to what sort of operation would do it though.
It's possible that one of the normal operations that produce NaN could be causing a negative variation (like +0/-0
or +Inf/-Inf
). But I would have thought that NaNs would print as nan
regardless of sign.
However, while the standard specifies in great detail how numbers are handled, it's strangely silent on how they're printed. The Wikipedia page for NaN lists these:
nan NaN NaN% NAN NaNQ
NaNS qNaN sNaN 1.#SNAN 1.#QNAN
-1.#IND -NaN NaN12345 -sNaN12300
with some of those showing sign and the extra payload.
Note that I'm talking about the IEEE standards here. The ISO C standards do indicate a limited number of forms but whether the sign and/or payload is printed is implementation-dependent. I can only assume that the later versions of the library have changed their behaviour.
How to fix it within the compiler, I'm not sure. I'd just take the pragmatic approach and run your output file through something like sed 's/-nan/nan/g'
. Hopefully that won't introduce other problems.
And you should also keep an eye on the form that allows the payload to be printed as well, though I'd only worry about that when the tests start failing again. But I'd put a comment somewhere near that sed
command indicating that it may happen at some time in the future. That way, at least the guy that follows you will understand why.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With