10-10-2010
11:07 PM
- last edited on
11-05-2024
02:48 PM
by
Content Cleaner
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++, whileNAN
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?
Solved! Go to Solution.
10-11-2010 10:15 AM
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
10-11-2010 05:43 PM
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).
10-11-2010 09:47 PM - edited 10-11-2010 09:49 PM
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'
10-12-2010 09:46 AM
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
10-12-2010 07:12 PM
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)
10-12-2010 08:02 PM
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
.