我正在编写Python 2.6代码,通过Windows中的COM与NI TestStand 4.2进行交互。 我想为一个variables创build一个“NAN”值,但是如果我把它传递给float('nan')
,TestStand将它显示为IND
。
显然,TestStand区分浮点“IND”和“NAN”值。 根据TestStand的帮助 :
IND
对应于Visual C ++中的Signaling NaN ,而 NAN
对应于QuietNaN 这意味着Python的float('nan')
实际上是通过COM传递的信号NaN 。 然而,从我所读到的有关NaN的信号来看,似乎NaN信号有点“异国情调”, 安静的NaN就是你的“常规”NaN。 所以我怀疑Python是否会通过COM传递一个Signaling NaN 。 我怎么能find一个Python的float('nan')
是否通过COM作为一个信号NaN或安静的NaN ,或可能不确定 ?
在与其他语言进行交互时,有什么办法可以让NaN与QuietNaN或Python中的不确定 信号发生关系? (也许使用ctypes
?)我认为这将是一个特定于平台的解决scheme,我接受这种情况。
更新:在TestStand序列编辑器中,我尝试了两个variables,一个设置为NAN
,另一个设置为IND
。 然后我将它保存到一个文件。 然后我打开文件并使用Python读取每个variables。 在这两种情况下,Python都会将它们看作一个nan
浮标。
我为你挖了一点,我想你可能会结合使用struct
模块与凯文的汇总图表上的信息。 他们解释了用于各种IEEE 754浮点数的确切位模式。
如果我读了这个IND
-eterminate值的主题,唯一可能需要小心的是,当直接用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'
参考凯文的总结图 ,这表明float('nan')
实际上技术上是不确定的价值,而scipy.nan
是一个安静的NaN。
让我们尝试制作一个Signaling 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'
不,信号NaN被转换成安静的NaN。
现在让我们试着直接制作一个安静的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'
所以这就是如何在Windows平台上使用struct.unpack()
至少使用一个适当的安静NaN。
nan的CPython定义
当Python报告一个nan
,这是从哪里来的?
Py_NAN
在CPython C源代码中
(Py_HUGE_VAL * 0.)
Py_HUGE_VAL
可能被定义为HUGE_VAL
– 它有一个说明它应该是HUGE_VAL
除了那个被破坏的平台上。 Py_NAN
定义的float('nan')
。 阅读Python和pywin32源代码
我看了一下pywin32
的C源代码,特别是构成Python↔COM翻译层的win32com。 该代码:
PyNumber_Float()
将其转换为Python float
(如果它尚未) PyFloat_AsDouble()
将其转换为普通的C double
值。
PyFloatObject
成员ob_fval
的C double
。 所以看起来好像我已经从COM接口跟踪了一个NaN
到一个包含Py_NAN
的普通C double
类型,无论结果是在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)
但是,这仍然出现在TestStand作为IND
。 于是我创建了一个变量设置为IND
和NAN
的TestStand文件,并从Python读取值。 事实证明,TestStand的NAN
值为FFFF000000000001
。 根据凯文的总结图是负南宁。 TestStand的IND
确实具有不确定的预期值, FFF8000000000000
。
成功
所以,毕竟,我已经成功地在Python中设置了TestStand中的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)
约翰·库克在这方面有一个很好的帖子,可能会有所帮助:
更新 :不会工作吗?
In [144]: import scipy In [145]: scipy.nan Out[145]: 1.#QNAN In [146]: scipy.inf Out[146]: 1.#INF In [147]: scipy.inf * 0 Out[147]: -1.#IND