What is result of comparison of double and NaN? - c++

I have the following program:
#include <iostream>
#include <cmath>
int main() {
double a = 1;
double b = nan("");
std::cout << (a > b) << std::endl;
std::cout << (b > a) << std::endl;
return 0;
}
Output:
0
0
In general from the meaning of nan - not a number it is clear that any operation with nan is essentially pointless. From IEEE-754 that I found in internet I found what if in FPU at least one of operands is nan the result is also nan, but I found nothing about comparison between normal value and nan as in example above.
What does standard say about it?

What does standard say about it?
The C++ standard does not say how operations on NaNs behave. It is left unspecified. So, as far as C++ is concerned, any result is possible and allowed.
ANSI/IEEE Std 754–1985 says:
5.7. Comparison
... Every NaN shall compare unordered with everything, including itself. ...
What unordered means exactly is shown in the Table 4 in the same section. But in short, this means that the comparison shall return false, if any of the operands is NaN, except != shall return true.

The 0 you're seeing means false in this case as that's what the stream shows for false by default. If you want to see it as true or false use std::boolalpha:
std::cout << std::boolalpha << (a > b) << std::endl;
Whey comparing floating point values where one of the values is nan then x<y, x>y, x<=y, x>=y, and x==y will all evaluate to false, whereas x!=y will always be true. Andrew Koenig has a good article on this on the Dr Dobbs website.
When you think about it the result cannot be nan since comparison operators need to return a boolean which can only have 2 states.

0 here means false.
Nan is not equal or comparable to any value so the result of operation is false(0).

Well, on top of #user2079303 pretty good answer, there are two NaNs: quiet NaN and signaling NaN. You could check std::numeric_limits<T>::has_signaling_NaN on your platform is signaling NaN is available. If it is true and value contains std::numeric_limits<T>::signaling_NaN, then
When a signaling NaN is used as an argument to an arithmetic expression, the appropriate floating-point exception may be raised and the NaN is "quieted", that is, the expression returns a quiet NaN.
To really get FP exception you might want to set FPU control word (for x87 unit) or MXCSR register (for SSE2+ unit). This is true for x86/x64 platform, check your platform docs for similar functionality

Related

When does NaN not propagate in C++?

NaN propagates through "most" operations as described in NaN - Wikipedia.
I would like to know the operations which NaN does NOT propagate. For example, I'm coding in C++ and found that following code prints 1, which is not NaN.
const double result = std::pow(1, std::numeric_limits<double>::quiet_NaN());
std::cout << result << std::endl;
For std::powfunction, this behavior is described in std::pow - cppreference.com.
Could you share any other examples?
Here's an example demonstrating functions of NaN which return non-NaN. The list is in IEEE 754-2008, 9.2.1 Special values (there are some others functions, but they don't seem to be implemented in C++):
#include <cmath>
#include <limits>
#include <iostream>
int main()
{
const auto nan=std::numeric_limits<double>::quiet_NaN();
const auto inf=std::numeric_limits<double>::infinity();
std::cout << std::hypot(nan,inf) << '\n';
std::cout << std::hypot(inf,nan) << '\n';
std::cout << std::pow(nan, 0) << '\n';
std::cout << std::pow(1,nan) << '\n';
}
The output is:
inf
inf
1
1
std::pow is not really an operator in the sense that something like the multiplication in a * b is an operation. It's a function. And functions can have branches which can deal with a NaN as they please. Another similar std function is, in a sense, std::is_nan. This doesn't propagate NaN either: it returns a bool which is implicitly convertible to a numeric type:
std::is_nan(std::is_nan(a))
is false for any type a that allows the expression to compile. Other examples include std::fpclassify and std::isfinite. I particularly like std::fpclassify as an example since it has an int return type, so really it's no less of a numeric function than pow!
Note that the implicit conversion of NaN to bool is defined to be false true according to the accepted answer to this question, which is important. It allows !, &&, and || to work with an NaN. Finally, the expression separator operator , doesn't propagate NaN either, and an NaN on the unused branch of a ternary conditional operation is ignored.
The other case I would try is pow(0, NaN). If one has pow(0,0) == 1 then one should expect
pow(0, NaN) == 1
There is a rationale for this, and actually it is needed for consistent behavior.
Even though there is no IEEE standard dictating the behavior of all elementary functions with respect to NaN, there is a very basic rule:
If for all finite point numbers x including +inf and -inf (but excluding NaN) we have
f(const1, x) == const2
then (and only then) one also must return a non-NaN result
f(const1, NaN) == const2
#Long explanation
This is because NaN represents "undefined" or "any other numeric value from -inf .. inf". Why? Consider the prototypical example 0/0.
If one has the equation
b = a * x
and wants to solve for x. Clearly the solution is
x = b/a
Now if a == b == 0 then the original equation has infinitely many solutions, namely all finite numbers x. That's why NaN means "unspecified" and 0/0 == NaN. Now if an unspecified number (i.e. NaN) enters a function as an argument, it most often will cause an "unspecified" answer. The exception is where the output does not depend on the input, and in this case one should/must not return NaN.
Consider
pow(1, a/b)
This expression always evaluates to 1 for nonzero a and b, which makes sense from a mathematical point of view as the 1^x in a mathematical sense does not depend on x. So also numerically one would require that for a = 0 or b = 0 (and hence x=NaN) one also obtains 1.
So if one agrees upon the fact that
pow(1,-inf) = pow(1,inf) = 1
then one also has to define
pow(1,NaN) = 1
for consistent behavior. The same applies to pow(0,c) but also evaluation of a polynomial of degree zero should generate a non-NaN output on NaN input.
Note: this reasoning can be applied to any function, including the built-in operators.

How to set returned value of log10(0)?

Code:
#include <iostream>
#include <math.h>
using namespace std;
int main ()
{
double result = log10(0.0);
cout << result;
}
When I execute log10(0) in C++, It prints to me -inf.
Is it fixed for every library/compiler I'll use?
Or could it change in different platforms?
How would you manage the pole error keeping double?
According to cplusplus, it depends on the library what you get for log10(0). However, in general the value of log10(0) is not defined (can be -inf if you like, but it is not a real number). Usually, you should prevent such undefined results (not undefined in the C++ sense of Undefined Behaviour, but in a mathematical sense) before they happen. E.g.
double x;
x = foo();
if ( x <= 0 ) {
/* handle this case extra */
else {
y = log10(x);
}
What value you use in the case of log10(0) depends very much on your application. However, I think it is easier to check for 0 before doing the calculation instead of relying on log10(0) returning some particular value (as it might be -inf or something completely different).
The behavior is very clear-cut for log10 for floating point implementations that are IEC 60559 compliant:
If the argument is ±0, -∞ is returned and FE_DIVBYZERO is raised.
If the argument is 1, +0 is returned
If the argument is negative, NaN is returned and FE_INVALID is raised.
If the argument is +∞, +∞ is returned
If the argument is NaN, NaN is returned
This list would allow you to conditionally handle each case for compliant implementations. But honestly, we know that only the range (+0, +∞) is supported, so whether your implementation is compliant or not you could simply guard your log10 with an if-block.
A great way to write this if-block is with isnormal if you don't want to allow denormals or isfinite if you do want to support denormals. For example, given a floating point variable foo:
if(isfinite(foo) && foo > 0) {
cout << log10(foo) << endl;
} else {
cout << "foo is invalid\n";
}
But the answer to your question is no -∞ will not always be returned. But C++ does guarantee a return: Given log10(foo):
If foo is a float the return will always be -HUGE_VALF
If foo is a double the return will always be -HUGE_VAL
If foo is a long double the return will always be -HUGE_VALL
On implementations that support floating-point infinities, these macros always expand to the positive infinities of float, double, and long double, respectively [source]
Whether your implementation supports infinity or whether these values expand to the maximum floating point value, the right way to handle this is still probably isnormal/isfinite but you could also test the return of log10:
const auto result = log10(foo);
if(is_same_v<decltype(foo), float> && result == -HUGE_VALF ||
is_same_v<decltype(foo), double> && result == -HUGE_VAL ||
is_same_v<decltype(foo), long double> && result = -HUGE_VALL) {
cout << "foo is invalid\n";
} else {
cout << result << endl;
}
Well c++ ref gives clear answer: cpp ref.
If the argument is ±0, -∞ is returned and FE_DIVBYZERO is raised.
So yes, log10(0) will give you -inf, doesn't matter what library/compiler you use (as long as it's in line with spec).
In math there is no option to calculate log(0)

How to compare two NAN values in C++

I have an application in which a code area produces NAN values. I have to compare the values for equality and based on that execute the rest of the code.How to compare two NAN values in C++ for equality?
Assuming an IEEE 754 floating point representation, you cannot compare two NaN values for equality. NaN is not equal to any value, including itself. You can however test if they are both NaN with std::isnan from the <cmath> header:
if (std::isnan(x) && std::isnan(y)) {
// ...
}
This is only available in C++11, however. Prior to C++11, the Boost Math Toolkit provides some floating point classifiers. Alternatively, you can check if a value is NaN by comparing it with itself:
if (x != x && y != y) {
// ...
}
Since NaN is the only value that is not equal to itself. In the past, certain compilers screwed this up, but I'm not sure of the status at the moment (it appears to work correctly with GCC).
MSVC provides a _isnan function.
The final alternative is to assume you know the representation is IEEE 754 and do some bit checking. Obviously this is not the most portable option.
Regarding pre-C++11, there's a boost for that, too.
#include <boost/math/special_functions/fpclassify.hpp>
template <class T>
bool isnan(T t); // NaN.
Any given NaN is not equal to anything, it will never be equal to any other NaN, so comparing them against each other is a futile exercise.
From GNU docs:
NaN is unordered: it is not equal to, greater than, or less than anything, including itself. x == x is false if the value of x is NaN. source

Is there a double value which will remain itself despite any computation applied to it?

On the Windows XP..7 platforms, for x86 instruction sets, using standard C++ or a Microsoft compiler, is there a value I can assign a double which, when other computations are applied to it, will always result in that same value?
e.g.
const double kMagicValue = ???;
double x = kMagicValue;
cout << x * 9.1; // still outputs kMagicValue
As I understand it, there is a floating point error condition that once trigged, the remainder of all floating point computations will result in NAN or something similar...
I ask because I have a series of functions that try to compute a double for a given input, and for some inputs, "no answer (NAN)" is a good output (conceptually).
And I want to be able to be lazy, and string together computations that should, if any part results in NAN, result as a whole in NAN (i.e. kMagicValue).
Quiet NaN should do just fine. You can get it from std::numeric_limits<double>::quiet_NaN() by including the <limits> header. There's also a signaling NaN, but using it will usually result in an exception.
Remember however, that you can't simple use mydouble == qNaN, since NaN compares equal to nothing, not even itself. You have to use that property of NaN to test it: bool isNaN = mydouble != mydouble;.
Any floating point operation involving NaN results in NaN again (to my knowledge). Moreover, NaN compares unequal to itself, and it is unique among IEEE754 floats with this property. So, to test for it:
bool is_nan(double x) { return x != x; }
If you have C++11 support, you can use std::isnan(x) != 0 or std::fpclassify(x) == std::FP_NAN from <cmath> instead [thanks #James Brock].
To make it:
double make_nan() {
assert(std::numeric_limits<double>::has_quiet_NaN);
return std::numeric_limits<double>::quiet_NaN();
}
You shouldn't rely on NaN to do the job. It will always compare false to any value, including itself, and you have to make sure that the platform respects IEEE754 semantics to a certain extent (this includes having a NaN in the first place).
See horror stories there: Negative NaN is not a NaN?
If you really want this approach, and you are confident enough about IEEE754 support, be sure to compile with /fp:precise (since you use MSVC) so that the compiler doesn't optimize away stuff like 0 * NaN. Be aware that this might impact performance.
To get a NaN,
std::numeric_limits<double>::quiet_NaN()
To test for NaN
inline bool is_NaN(double x) { return !(x == x); }
But this approach is probably more trouble than it is worth. I'd rather use exceptions for control flow here.
The right thing to use is boost::optional<double>, but it can be a little verbose at some places
[Also, the Haskell language has first-class support for these kind of control flow, if C++ is not a must-go option, Maybe you can give it a try.]
Actually there is a special floating point value named Not-A-Number (NaN). Any expression with NaN involved will return NaN.
#include <limits>
numeric_limits<double>::quiet_NaN()
Infinity not always remains the same. For example it become NaN if you try to divide on Infinity.

C++ ceil and negative zero

On VC++ 2008, ceil(-0.5) is returning -0.0. Is this usual/expected behavior? What is the best practice to avoid printing a -0.0 to i/o streams.
ceil in C++ comes from the C standard library.
The C standard says that if a platform implements IEEE-754 arithmetic, ceil( ) behaves as though its argument were rounded to integral according to the IEEE-754 roundTowardPositive rounding attribute. The IEEE-754 standard says (clause 6.3):
the sign of the result of conversions,
the quantize operation, the
roundToIntegral operations, and the
roundToIntegralExact is the sign of
the first or only operand.
So the sign of the result should always match the sign of the input. For inputs in the range (-1,0), this means that the result should be -0.0.
This is correct behavior. See Unary Operator-() on zero values - c++ and http://en.wikipedia.org/wiki/Signed_zero
I am partial to doing a static_cast<int>(ceil(-0.5)); but I don't claim that is "best practice".
Edit: You could of course cast to whatever integral type was appropriate (uint64_t, long, etc.)
I can't say that I know that it is usual, but as for avoiding printing it, implement a check, something like this:
if(var == -0.0)
{
var = 0.0;
}
// continue
Yes this is usual.
int number = (int) ceil(-0.5);
number will be 0
I see why ceil(-0.5) is returning -0.0. It's because for negative numbers, ceil is returning the integer part of the operand:
double af8IntPart;
double af8FracPart = modf(-0.5, & af8IntPart);
cout << af8IntPart;
The output here is "-0.0"