如何区分不同类型的NaN float在Python中 [英] How to distinguish different types of NaN float in Python

查看:376
本文介绍了如何区分不同类型的NaN float在Python中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编写Python 2.6代码,通过Windows中的COM与 NI TestStand 4.2接口。我想为一个变量做一个NAN值,但如果我传递 float('nan'),TestStand显示为 IND



显然,TestStand区分浮点IND和NAN值。根据 TestStand帮助




  • IND 对应于Visual C ++中的 Signaling NaN

  • NAN 对应于 QuietNaN



这意味着Python的 float('nan')在通过COM传递时实际上是一个信令NaN 。但是,根据我已经阅读的 Signaling NaN ,看起来信号NaN 有点异国情调,安静NaN 常规NaN。所以我怀疑Python将通过COM传递信令NaN 我如何找出是否 c> float('nan')作为信号NaN 安静



有任何方法可以使信号NaN em>与 不确定在Python中,与其他语言接口? (使用 ctypes 也许?)我认为这将是一个平台特定的解决方案,我会接受在这种情况下。



更新:在TestStand序列编辑器中,我尝试了两个变量,一个设置为 NAN ,另一个设置为 IND 。然后我把它保存到一个文件。然后我打开文件,并使用Python读取每个变量。在这两种情况下,Python都将它们读为 nan float。

解决方案

我为你挖了一下,我想你可以使用 struct 模块结合 Kevin的摘要图表。它们解释了用于各种IEEE 754浮点数的确切位模式。



如果我阅读主题,你唯一需要注意的是在这个 IND - 确定值,是当该值直接在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'

参考 Kevin的摘要图表,表明 float('nan')实际上是不确定值,而 scipy.nan 是一个安静的NaN。 p>

让我们尝试做一个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'

这是如何使用 struct.unpack() - 至少在Windows平台上使一个正确的安静NaN。


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.

解决方案

I dug a bit for you, and I think you might be able to use the struct module in combination with the information on at Kevin's Summary Charts. They explain the exact bit patterns used for the various kinds of IEEE 754 floating point numbers.

The only thing you probably will have to be careful for, if I read the topics on this IND-eterminate value, is that that value tends to trigger some kind of floating point interrupt when assigned directly in C code, causing it to be turned into a plain NaN. Which in turn meant those people were advised to do this kind of thing in ASM rather than C since C abstracted that stuff away.. Since it is not my field, and that I am not sure to what extent this kind of value would mess with Python, I figured I'd mention it so you can at least keep an eye for any such weird behaviour. (See the accepted answer for this question).

>>> import struct

>>> struct.pack(">d", float('nan')).encode("hex_codec")
'fff8000000000000'

>>> import scipy
>>> struct.pack(">d", scipy.nan).encode("hex_codec")
'7ff8000000000000'

Referring to Kevin's Summary Charts, that shows that float('nan') is actually technically the Indeterminate value, while scipy.nan is a Quiet NaN.

Let's try making a Signaling NaN, and then verify it.

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

No, the Signaling NaN gets converted to a Quiet NaN.

Now let's try making a Quiet NaN directly, and then verify it.

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

So that's how to make a proper Quiet NaN using struct.unpack()--at least, on a Windows platform.

这篇关于如何区分不同类型的NaN float在Python中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆