Reputation: 9662
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).
Upvotes: 1
Views: 239
Reputation: 56976
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.]
Upvotes: 2
Reputation: 477368
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();
}
Upvotes: 3
Reputation: 1448
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.
Upvotes: 2
Reputation: 131829
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;
.
Upvotes: 3