numpy.float96的奇怪行为

4 投票
3 回答
970 浏览
提问于 2025-04-15 15:03

我漏掉了什么:

In [66]: import numpy as np

In [67]: np.float(7.0 / 8)
Out[67]: 0.875 #OK

In [68]: np.float32(7.0 / 8)
Out[68]: 0.875 #OK

In [69]: np.float96(7.0 / 8)
Out[69]: -2.6815615859885194e+154 #WTF

In [70]: sys.version
Out[70]: '2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)]'

编辑。 在cygwin上,上面的代码运行得很好:

$ python
Python 2.5.2 (r252:60911, Dec  2 2008, 09:26:14)
[GCC 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> np.float(7.0 / 8)
0.875
>>> np.float96(7.0 / 8)
0.875

为了完整性,我在普通的python中检查了这段代码(不是在Ipython中):

C:\temp>python
Python 2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> np.float(7.0 / 8)
0.875
>>> np.float96(7.0 / 8)
-2.6815615859885194e+154
>>>

编辑

我在Numpy的bug跟踪网站上看到三个错误报告(976902,和884),但这个似乎和字符串表示没有关系。因此我开了一个新的bug(1263)。会在这里更新进展情况

3 个回答

1

在1.3.0版本中,针对Windows系统的长双精度格式化问题进行了一些修复。具体的修复内容可以查看以下链接:http://projects.scipy.org/numpy/changeset/6219http://projects.scipy.org/numpy/changeset/6218http://projects.scipy.org/numpy/changeset/6217

2

这个问题是因为mingw编译器(官方numpy二进制文件使用的编译器)和微软的运行时(printf函数来自的地方)之间不兼容造成的。

微软的编译器把long double和double看作是一样的类型,微软的C运行时(包括printf)也是这样认为的。而mingw编译器出于某种原因,把long double定义得足够大,可以存储80位的高精度数字,但微软的printf并不知道这一点,所以它无法正确打印long double。

我们通过使用自己的格式化函数解决了一些问题,但我认为真正的解决办法是强制在使用mingw编译时,把long double当作double来处理。我想这个会在numpy 1.5.0版本中实现。

2

这对我来说运行得很好:

In [1]: import numpy as np

In [2]: np.float(7.0/8)
Out[2]: 0.875

In [3]: np.float96(7.0/8)
Out[3]: 0.875

你用的是什么版本的Numpy?我用的是Python 2.6.2和Numpy 1.3.0,系统是64位的Vista。

我在另一台电脑上试了同样的东西,那台电脑是32位的XP,使用的是Python 2.5.2和Numpy 1.2.1,结果让我很惊讶,我得到了:

In [2]: np.float96(7.0/8)
Out[2]: -2.6815615859885194e+154

经过一些调查,我在32位XP上安装了Python 2.6.3和Numpy 1.3.0,发现:

In [2]: np.float96(7.0/8)
Out[2]: 0.875

所以这肯定是旧版本的Numpy或者旧版本的Python中的一个bug……

撰写回答