NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

Setting NAN float value from Python

Solved!
Go to solution

I'm writing Python 2.6 code that interfaces with NI TestStand 4.2 via COM in Windows. I want to make a "NAN" value for a variable, but if I pass it float('nan'), TestStand displays it as IND. That is, my code has something like:

 

 

locals_prop_object.NewSubProperty(var_name, win32com.client.constants.PropValType_Number, False, "", 0)
# Set the initial value to NaN--although it appears in TestStand as 'IND'.
locals_prop_object.SetValNumber(var_name, 0, float('nan'))

 

 

Apparently TestStand distinguishes between floating point "IND" and "NAN" values. According to TestStand help:

  • IND corresponds to Signaling NaN in Visual C++, while
  • NAN corresponds to QuietNaN

 

That implies that Python's float('nan') is effectively a Signaling NaN when passed through COM. However, from what I've read about Signaling NaN, it seems that Signaling NaN is a bit "exotic" and Quiet NaN is your "regular" NaN. So I have my doubts that Python would be passing a Signaling NaN through COM (how could I verify this?).

 

So, any ideas how Python float('nan') becomes TestStand 'IND', in the Python->COM->TestStand data flow?

 

0 Kudos
Message 1 of 7
(9,660 Views)

It is unlikely that the bits of the value are altered in any way when passed through COM to TestStand. They are probably just copied directly. Thus the value generated by float('nan') is likely the equivalent to what TestStand shows as IND. Is float in python a 32-bit floating point value? If so then there is an implicit conversion to double (64-bit floating point) that python is doing. You might want to try something like double('nan') instead. I don't know much about python though, so perhaps there is a completely different way to do this in python that would get you the appropriate value.

 

Hope this helps,

-Doug

0 Kudos
Message 2 of 7
(9,650 Views)

A python float is implemented internally using the C double type. From what investigation I've done so far, it looks as though the value gets copied into the COM interface without any significant conversion. So I will try to investigate further at the low level whether Python's float('nan') is a signalling or quiet NaN (in Windows--this is most likely platform-specific).

0 Kudos
Message 3 of 7
(9,637 Views)

I asked this question on StackOverflow.

 

From the responses, and further investigation, I've found the following:

 

It is possible to inspect the value of a NaN using the Python struct module.

 

>>> import struct

>>> struct.pack(">d", float('nan')).encode("hex_codec")
'fff8000000000000'

 

With reference to a table in IEEE-754 References, we can see that this is technically the Indeterminate value.

 

It is possible to construct a real Quiet NaN in Python using the struct module's struct.unpack:

 

>>> quiet_nan = struct.unpack(">d", "\x7f\xf8\x00\x00\x00\x00\x00\x00")[0]
>>> struct.pack(">d", quiet_nan).encode("hex_codec")
'7ff8000000000000'

 

I'm home sick today, without access to TestStand, but I reckon I should be able to pass this quiet_nan value to SetValNumber and it should appear as NAN in TestStand. I'll try it when I have the opportunity.

 

Interestingly, I was not able to use the same method to explicitly construct a Signaling NaN. It got converted to a Quiet NaN. So perhaps the TestStand help should be updated to explicitly refer to IEEE-754 Indeterminate value which appears as IND in TestStand.

>>> import struct

>>> struct.pack(">d", float('nan')).encode("hex_codec")
'fff8000000000000'
0 Kudos
Message 4 of 7
(9,630 Views)

Interesting. From our recent documentation for constant values: "Indeterminate Number (IND) is a special type of NaN. In comparison operations, IND and NAN are equivalent." So perhaps that is why python is using IND for float('nan') it is still technically equivalent to nan, it's just a special case of nan.

 

-Doug

0 Kudos
Message 5 of 7
(9,606 Views)
Solution
Accepted by topic author cmcqueen1975

Now I've tried this with NI TestStand. First I tried:

 

quiet_nan = struct.unpack(">d", "\x7f\xf8\x00\x00\x00\x00\x00\x01")[0]
# Set the variable's value in TestStand
locals_prop_object
.SetValNumber(var_name, 0, quiet_nan)

 

But that still appeared in TestStand as IND. So then I created a TestStand file with variables set to IND and NAN, and read the values from Python. It turns out that TestStand's NAN has a value of FFFF000000000001. According to Kevin's Summary Charts that is a negative quiet NAN.

 

So, finally, this works (although probably is platform-specific; it works for me on Windows XP):

 

# Make a NAN suitable for TestStand
teststand_nan
= struct.unpack(">d", "\xff\xff\x00\x00\x00\x00\x00\x01")[0]
# Set the variable's value in TestStand
locals_prop_object
.SetValNumber(var_name, 0, teststand_nan)

Message 6 of 7
(9,590 Views)

Just a PS: I also found, when reading the IND and NAN values from TestStand: TestStand's IND does have the expected value for Indeterminate, FFF8000000000000.

0 Kudos
Message 7 of 7
(9,585 Views)