LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

literal NaN

As it turns out, NI has a union for double constants set up in math.h, using a char array and a double:

 

#ifndef _DBL_CONST_T
#define _DBL_CONST_T
typedef const union {
    unsigned char a[8];
    double val;
} _DoubleConst_t;
#endif

 

So, if you set the char array to the NaN bit pattern, then you could reference  DoubleConst.val as a NaN literal without making a function call.

 

So let's see, how can we get all 1's into the char array as an initializer so that the compiler does it at compile time?  

 

_DoubleConst_t dNaN = {'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xff'};           ?

 

Lemme try that ...

 

Compiles OK ...

 

int i = IsNotANumber(dNaN.val);      yields a '1' (true) so the NaN value is good, 

 

so now, can I use it as an initializer in a top level variable?

 

dValue = dNaN.val;

 

NO!  Compiler says it's not a constant!!!

 

Woe is me ...

 

 

 

 

0 Kudos
Message 11 of 21
(1,714 Views)

The flaw in my thinking is that the initializer executes at run time, not compile time.

 

So I think there's no way to do it at all,  it takes a union to get under the type system in C, and we see that doesn't work without runtime support.

 

NI would have to modify the compiler to get this going I should think, or maybe the preprocessor.

 

 

Message Edited by menchar on 06-17-2010 10:29 AM
0 Kudos
Message 12 of 21
(1,714 Views)
jr had it right.
0 Kudos
Message 13 of 21
(1,709 Views)

On some previous occasions when I had to use constant initialisers for structure fields that were not fully defined until runtime, I added an indirection to the field to get around the problem. So instead of trying:

 

    typedef struct {

        int val;

        int param;

    } structStore;

    static int default = 99;

    static stuctStore abc = {default, 0};

 

which doesn't work, you can adjust the code slightly as follows:

 

    typedef struct {

        int *val;

        int param;

    } structStore;

 

    static int default = 99;

    static stuctStore abc = {&default, 0};

 

which does. Maybe you can have a similar approach to your NaNs, by adding an indirection somewhere to get around the constant initialiser problem?

 

JR

0 Kudos
Message 14 of 21
(1,674 Views)

Well, I think the compiler may not like the idea of a dereference in the initializer of a top level variable.  i.e. that still seems to me like it's a runtime thing.

 

double myDouble =  *(dNaN.val);

 

I'll try this but I suspect the compiler will complain.

0 Kudos
Message 15 of 21
(1,652 Views)

Didn't seem to work.

 

As an aside, as I recall Fortran 77 allows runtime-like syntax in an initializer or a common (i.e. global) variable:  you wrote code to express how you wanted things initialized, and it looked just like run-time code, but it was "executed" by the compiler at compile time.

 

Or maybe this was a Hewlett Packard extension to Fortran 77.

 

Menchar

0 Kudos
Message 16 of 21
(1,649 Views)

And here's another thought -

 

On any of the numeric controls, when you establish the default value for a control with a floating point type, you should be able to select NaN.  You can select positive and negative infinity for the max and min values, so why not NaN for the default?

 

It seems to me good practice to purposely spoil the default value for doubles to NaN so as to distinguish the value from the otherwise benign "0.0" or other legitimate numeric value.

 

Menchar

0 Kudos
Message 17 of 21
(1,580 Views)

I'm not sure I understand why the NotANumber() function won't work for you.

 

I use it all the time, I mostly initialize variables with it to give an indication that the value returned from a function is invalid.

 

Can you enlighten me as to why you absolutely need a constant?

 

Perhaps you can do something like this instead?:

 

const double NaN = NotANumber();

Martin Fredrickson
Test Engineer

Northrop Grumman
Advanced Systems and Products
San Diego, CA 92128
0 Kudos
Message 18 of 21
(1,570 Views)

Try using NotANumber() to initialize a top level variable.

0 Kudos
Message 19 of 21
(1,565 Views)

What do you mean by a "top level variable"?

 

Do you mean a global?

Martin Fredrickson
Test Engineer

Northrop Grumman
Advanced Systems and Products
San Diego, CA 92128
0 Kudos
Message 20 of 21
(1,540 Views)