Compile-time constant quiet NaN (double) ???

L

Lionel B

Running VC++ 6 under Win2K on i386.

I would like to assign a (compile-time) constant that resolves to a
quiet NaN (of type double)

I can assign a quiet NaN to a *variable* (of type const double, say)
by eg.:

const double qnan = fmod(1.0,0.0);

but - for efficiency reasons - what I really want is a (compile-time)
constant:

#define QNAN ???

Now I have established that (on my system at least) the type __int64
is the same size as a double and that a quiet NaN corresponds to an
__int64 with a value of -2251799813685248. However, the "obvious":

#define QNAN -2251799813685248i64

will not work, since an assignment eg.:

double x = QNAN;

will cause the QNAN to be *cast* to type double, so that x will have
the value -2251799813685248.0

Is there a way to "turn off" automatic casting, so that an assignation
as above simply copies byte-for-byte?

Any ideas much appreciated,
 
R

Rolf Magnus

Lionel said:
Running VC++ 6 under Win2K on i386.

I would like to assign a (compile-time) constant that resolves to a
quiet NaN (of type double)

I can assign a quiet NaN to a *variable* (of type const double, say)
by eg.:

const double qnan = fmod(1.0,0.0);

but - for efficiency reasons - what I really want is a (compile-time)
constant:

#define QNAN ???

Don't use #define for that. Why do you believe it could be more
efficient than a constant anyway?
Now I have established that (on my system at least) the type __int64
is the same size as a double and that a quiet NaN corresponds to an
__int64 with a value of -2251799813685248. However, the "obvious":

#define QNAN -2251799813685248i64

will not work, since an assignment eg.:

double x = QNAN;

will cause the QNAN to be *cast* to type double, so that x will have
the value -2251799813685248.0

It's converted, not cast.
Is there a way to "turn off" automatic casting, so that an assignation
as above simply copies byte-for-byte?

Instead, I'd recommend to the standard C++ way to get the quiet NaN:

// #include <limits>
double x = std::numeric_limits<double>::quiet_NaN();
 
K

Karl Heinz Buchegger

Lionel said:
Running VC++ 6 under Win2K on i386.

I would like to assign a (compile-time) constant that resolves to a
quiet NaN (of type double)

I can assign a quiet NaN to a *variable* (of type const double, say)
by eg.:

const double qnan = fmod(1.0,0.0);

but - for efficiency reasons - what I really want is a (compile-time)
constant:

Hmm. I wonder how many nanoseconds this will take on program startup
for a global constant. Is this really an efficiency problem?
#define QNAN ???

Now I have established that (on my system at least) the type __int64
is the same size as a double and that a quiet NaN corresponds to an
__int64 with a value of -2251799813685248. However, the "obvious":

#define QNAN -2251799813685248i64

will not work, since an assignment eg.:

double x = QNAN;

will cause the QNAN to be *cast* to type double, so that x will have
the value -2251799813685248.0

Is there a way to "turn off" automatic casting, so that an assignation
as above simply copies byte-for-byte?

_int64 qnan = -2251799813685248i64;
double x = (double*)&qnan;

or hidden in a function:

static _int64 myqnan = -2251799813685248i64;
inline double qnan()
{
return *(double*)&myqnan;
}

double x = qnan();
 
A

Alf P. Steinbach

* Karl Heinz Buchegger said:
Hmm. I wonder how many nanoseconds this will take on program startup
for a global constant. Is this really an efficiency problem?


_int64 qnan = -2251799813685248i64;
double x = (double*)&qnan;

or hidden in a function:

static _int64 myqnan = -2251799813685248i64;
inline double qnan()
{
return *(double*)&myqnan;
}

double x = qnan();

A bit more general (standard C++ doesn't have an _int64 type),


STATIC_ASSERT( std::numeric_limits<double>::is_iec559 );
STATIC_ASSERT( std::numeric_limits<double>::has_quiet_NaN );
STATIC_ASSERT( sizeof(unsigned) == 4 );
STATIC_ASSERT( sizeof(double) == 8 );

static unsigned const nanData[2] = { 0x00000000, 0x7FF80000 };
extern double const quietNaN = *reinterpret_cast<double const*>(
&nanData[0] );

bool assertQuietNaNIsOk()
{
double const actualQNaN = std::numeric_limits<double>::quiet_NaN();
unsigned const* actualData = reinterpret_cast<unsigned const*>(
&actualQNaN );

assert((
"::quietNan is not the quiet NaN value",
std::equal( nanData, nanData+2, actualData )
));
return true;
}

static bool const TEMPNAME = assertQuietNaNIsOk();


to which some module initialization function must be added to ensure that the
assert at the end is executed.

It seems like a lot of complication for a once-only nanosecond-level
"improvement" compared to just


STATIC_ASSERT( std::numeric_limits<double>::has_quiet_NaN );
double const quietNaN = std::numeric_limits<double>::quiet_NaN();


Heh...
 
K

Karl Heinz Buchegger

Alf P. Steinbach said:
It seems like a lot of complication for a once-only nanosecond-level
"improvement" compared to just

STATIC_ASSERT( std::numeric_limits<double>::has_quiet_NaN );
double const quietNaN = std::numeric_limits<double>::quiet_NaN();

I didn't know about the quiet_Nan in the numeric_limits.
Thanks for bringing this up.
 
L

Lionel B

Rolf Magnus said:
Don't use #define for that. Why do you believe it could be more
efficient than a constant anyway?

I imagined (erroneously?) that there would be an (admittedly
miniscule) overhead in fetching a constant from memory, as compared to
using a hard-coded compile-time constant.

Efficiency *is* an issue for me, because I intend to use quiet NaN as
a value for "missing" data, frequently in vast arrays of doubles (it
has the advantage that arithmetical operations where an argument is a
quiet NaN result in a quiet NaN, which is exactly how I would like
missing data to behave).

So I may frequently have to set zillions of doubles to quiet NaN:

double qnan = std::numeric_limits<double>::quiet_NaN();
...
double* data; // huge array
pend = data+(size of array)
...
for (double* p=data; p!=pend; p++) if (some condition) *p = qnan;
or
for (double* p=data; p!=pend; p++) if (*p is quiet NaN) (do
something);

Apropos of which, what is the most efficient way to test for x = a
quiet NaN...?

_isnan(x)

works (although I guess it might evaluate to true for a signalling NaN
too (probably not a problem), as does

(_fpclass(x) == _FPCLASS_QNAN)

Curiously,

(x == qnan)

appears to evaluate to true for *any* double x (???)

/snip/
Instead, I'd recommend to the standard C++ way to get the quiet NaN:

// #include <limits>
double x = std::numeric_limits<double>::quiet_NaN();

Yes, I guess that is the way to go.

Thanks,
 
A

Alf P. Steinbach

* (e-mail address removed) (Lionel B) schriebt:
Curiously,

(x == qnan)

appears to evaluate to true for *any* double x (???)

Except for the nan; that is by definition (IEEE/IEC standard).
 

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

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top