How to distinguish different types of NaN float in Python

后端 未结 4 1221
悲&欢浪女
悲&欢浪女 2021-02-13 22:27

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\')

4条回答
  •  我在风中等你
    2021-02-13 23:13

    CPython definition of nan

    When Python reports a nan, where does that come from?

    • Result of a calculation (platform specific values?)
    • Py_NAN in the CPython C source code
      • defined as (Py_HUGE_VAL * 0.)
        • Value is platform-specific
        • Py_HUGE_VAL is probably defined as HUGE_VAL--it has a note to say it should be HUGE_VAL except on platforms where that is broken.
    • float('nan') which is defined from Py_NAN in CPython's C source code.

    Reading Python and pywin32 Source Code

    I've had a look at the C source code for pywin32, in particular win32com, which forms the Python↔COM translation layer. That code:

    • takes the input object
    • calls PyNumber_Float() to convert it to a Python float (if it isn't already)
    • calls PyFloat_AsDouble() to convert it to a plain C double value.
      • This simply returns the C double directly contained in the PyFloatObject member ob_fval.

    So it looks as though I've traced a NaN from the COM interface back to a plain C double type containing Py_NAN, whatever that turns out to be on the Windows platform.

    TestStand NAN Value

    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. TestStand's IND does have the expected value for Indeterminate, FFF8000000000000.

    Success

    So, after all that, I have succeeded in setting a NAN in TestStand, from Python:

    # 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)
    

提交回复
热议问题