Cra*_*een 10 python windows com interop nan
我正在编写Python 2.6代码,通过Windows中的COM 与NI TestStand 4.2连接.我想为变量创建一个"NAN"值,但如果我传递它float('nan')
,TestStand 会将其显示为IND
.
显然,TestStand区分浮点"IND"和"NAN"值.根据TestStand的帮助:
IND
对应于Visual C++中的信令NaN,而NAN
对应于QuietNaN这意味着Python 在通过COM时float('nan')
实际上是一个信令NaN.然而,从我读到的有关信号NaN的内容来看,似乎信号NaN有点"异国情调"而Quiet NaN是你的"常规"NaN.所以我怀疑Python会通过COM 传递信令NaN.我怎么能知道Python float('nan')
是通过COM作为信令NaN还是Quiet NaN传递,还是可能不确定?
在与其他语言连接时,有没有办法在Python中建立信令NaN与QuietNaN或Indeterminate?(ctypes
或许使用?)我认为这将是一个特定于平台的解决方案,在这种情况下我会接受.
更新:在TestStand序列编辑器中,我尝试制作两个变量,一个设置为NAN
,另一个设置为IND
.然后我把它保存到一个文件中.然后我打开文件并使用Python读取每个变量.在这两种情况下,Python都将它们作为nan
float 读取.
我为你挖了一下,我想你可以将这个struct
模块与Kevin的摘要图表中的信息结合使用.它们解释了用于各种IEEE 754浮点数的精确位模式.
如果我阅读关于此IND
-eminminate值的主题,那么您可能必须要小心的唯一事情是,当直接在C代码中分配时,该值往往会触发某种浮点中断,从而导致它变为简单的NaN.这反过来意味着那些人被建议在ASM中做这种事情而不是C,因为C抽象了那些东西.因为它不是我的领域,而且我不确定这种价值会在多大程度上混乱Python,我想我会提到它,所以你至少可以留意任何这种奇怪的行为.(请参阅此问题的已接受答案).
>>> import struct
>>> struct.pack(">d", float('nan')).encode("hex_codec")
'fff8000000000000'
>>> import scipy
>>> struct.pack(">d", scipy.nan).encode("hex_codec")
'7ff8000000000000'
Run Code Online (Sandbox Code Playgroud)
参考Kevin的摘要图表,它显示了float('nan')
技术上实际上是Indeterminate值,scipy.nan
而是一个安静的NaN.
让我们尝试制作一个信令NaN,然后验证它.
>>> try_signaling_nan = struct.unpack(">d", "\x7f\xf0\x00\x00\x00\x00\x00\x01")[0]
>>> struct.pack(">d", try_signaling_nan).encode("hex_codec")
'7ff8000000000001'
Run Code Online (Sandbox Code Playgroud)
不,信令NaN转换为安静的NaN.
现在让我们尝试直接制作一个Quiet NaN,然后验证它.
>>> try_quiet_nan = struct.unpack(">d", "\x7f\xf8\x00\x00\x00\x00\x00\x00")[0]
>>> struct.pack(">d", try_quiet_nan).encode("hex_codec")
'7ff8000000000000'
Run Code Online (Sandbox Code Playgroud)
这就是如何使用 - struct.unpack()
至少在Windows平台上制作适当的Quiet NaN .
nan 的 CPython 定义
当 Python 报告 a 时nan
,它来自哪里?
Py_NAN
在 CPython C 源代码中
(Py_HUGE_VAL * 0.)
Py_HUGE_VAL
可能被定义为HUGE_VAL
--它有一个注释说它应该是,HUGE_VAL
除非在那些被破坏的平台上。float('nan')
这是Py_NAN
在 CPython 的 C 源代码中定义的。阅读 Python 和 pywin32 源代码
我已经查看了 的 C 源代码pywin32
,特别是win32com
,它构成了 Python?COM 翻译层。那个代码:
PyNumber_Float()
将其转换为 Python float
(如果还没有)PyFloat_AsDouble()
将其转换为普通的 Cdouble
值。
double
直接包含在PyFloatObject
构件ob_fval
。所以看起来好像我已经NaN
从 COM 接口追溯到一个double
包含的普通 C类型Py_NAN
,无论结果是在 Windows 平台上。
TestStand NAN 值
现在我已经用 NI TestStand 试过了。首先我试过:
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)
Run Code Online (Sandbox Code Playgroud)
但它仍然出现在 TestStand 中IND
。然后我创建了一个 TestStand 文件,变量设置为IND
and NAN
,并从 Python 读取值。事实证明,TestStand 的NAN
值为FFFF000000000001
。根据凯文的总结图表,这是一个消极的安静 NAN。TestStandIND
确实具有Indeterminate的预期值,FFF8000000000000
。
成功
所以,毕竟,我已经成功地在 TestStand 中从 Python 设置了一个 NAN:
# 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)
Run Code Online (Sandbox Code Playgroud)