tags:

views:

750

answers:

4

In my application i have double (or float) variables that might be "empty", as in holding no valid value. How can i represent this condition with the built in types float and double?

One option would be a wrapper that has a float ad a boolean, but that can´t work, as my libraries have containers that store doubles and not objects that behave as doubles. Another would be using NaN (std::numeric_limits). But i see no way to check for a variable being NaN.

How would yourself solve the problem of needing a "special" float value to mean something other then the number?

Thanks!

+4  A: 

We have done that by using NaN:

double d = std::numeric_limits<double>::signaling_NaN();
bool isNaN = (d != d);

NaN values compared for equality against itself will yield false. That's the way you test for NaN, but which seems to be only valid if std::numeric_limits<double>::is_iec559 is true (if so, it conforms to ieee754 too).

In C99 there is a macro called isnan for this in math.h, which checks a floating point number for a NaN value too.

Johannes Schaub - litb
There may also be one in "<cmath>". http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.15
James Schek
thanks for the link. they noted correctly it's implementation dependant whether it's in it or not. It might slurp into because <cmath> includes math.h indirectly on those implementations.
Johannes Schaub - litb
It's better then to include math.h directly IMHO. anyway, i haven't found anything regarding that d == d is false for NaN in the standard, so i think it's more a feature of ieee754 than of C/C++. I'll update this answer if i find anything relevant to that question though.
Johannes Schaub - litb
Correct d != d -> d is NaN is a part of the ieee754 standard not the C/C++ standard... though unless you need to care about IBM mainframes it's pretty safe to assume ieee754 floats are what you have
Spudd86
+2  A: 

In Visual C++, there is a non-standard _isnan(double) function that you can import through float.h.

In C, there is a isnan(double) function that you can import through math.h.

In C++, there is a isnan(double) function that you can import through cmath.

As others have pointed out, using NaN's can be a lot of hassle. They are a special case that has to be dealt with like NULL pointers. The difference is that a NaN will not usually cause core dumps and application failures, but they are extremely hard to track down. If you decide to use NaN's, use them as little as possible. Overuse of NaN's is an offensive coding practice.

James Schek
<cmath> may be preferable for a C++ user.
strager
I wasn't sure if isnan in cmath was part of the standard. Will update.
James Schek
isnan is *not* part of the standard. it's therefor not guaranteed to appear in cmath. it's implementation specific when you have it in your files.
Johannes Schaub - litb
+2  A: 

It's not a built-in type, but I generally use boost::optional for this kind of thing. If you absolutely can't use that, perhaps a pointer would do the trick -- if the pointer is NULL, then you know the result doesn't contain a valid value.

Head Geek
I´ll check into this boost::optional. As to the pointer ideia, it is nice, and it should work in most cases. Unfortunetely my libraries want to store floats and not pointers.
David Reis
+1  A: 

One option would be a wrapper that has a float ad a boolean, but that can´t work, as my libraries have containers that store doubles and not objects that behave as doubles.

That's a shame. In C++ it's trivial to create a templated class that auto-converts to the actual double (reference) attribute. (Or a reference to any other type for that matter.) You just use the cast operator in a templated class. E.g.: operator TYPE & () { return value; } You can then use a HasValue<double>anywhere you'd normally use a double.

*Another would be using NaN (std::numeric_limits). But i see no way to check for a variable being NaN.*

As litb and James Schek also remarked, C99 provides us with isnan().

But be careful with that! Nan values make math & logic real interesting! You'd think a number couldn't be both NOT>=foo and NOT<=foo. But with NaN, it can.

There's a reason I keep a WARN-IF-NAN(X) macro in my toolbox. I've had some interesting problems arise in the past.

Mr.Ree