How to distinguish different types of NaN float in Python

Viewed 4317

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.

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 find out if a Python float('nan') is passed through COM as a Signaling NaN or Quiet NaN, or maybe Indeterminate?

Is there any way to make a Signaling NaN versus QuietNaN or Indeterminate in Python, when interfacing with other languages? (Using ctypes perhaps?) I assume this would be a platform-specific solution, and I'd accept that in this case.

Update: In the TestStand sequence editor, I tried making two variables, one set to NAN and the other set to IND. Then I saved it to a file. Then I opened the file and read each variable using Python. In both cases, Python reads them as a nan float.

4 Answers

From what I can gather, it seems there is some confusion as to thinking that the sign of a NaN determines whether or not it is quiet. On the contrary, the convention is that the most significant bit of the mantissa determines this. From Wikipedia (emphasis added):

In IEEE 754 standard-conforming floating-point storage formats, NaNs are identified by specific, pre-defined bit patterns unique to NaNs. The sign bit does not matter. Binary format NaNs are represented with the exponential field filled with ones (like infinity values), and some non-zero number in the significand field (to make them distinct from infinity values). The original IEEE 754 standard from 1985 (IEEE 754-1985) only described binary floating-point formats, and did not specify how the signaling/quiet state was to be tagged. In practice, the most significant bit of the significand field determined whether a NaN is signaling or quiet... The 2008 revision of the IEEE 754 standard (IEEE 754-2008) makes formal recommendations for the encoding of the signaling/quiet state. For binary formats, the most significant bit of the significand field should be an 'is_quiet' flag. I.e. this bit is non-zero if the NaN is quiet, and zero if the NaN is signaling.

Since most implementations are IEEE 754-2008 conformant, this is the convention you should follow. In general, you cannot plan on the sign bit being consistent for NaNs, even for different NaNs on the same platform. Under this convention, float('nan') and scipy.nan both seem to be quiet NaNs, at least in the cases discussed above.

Related