Python math与numpy模块结果不同?

7 投票
3 回答
7585 浏览
提问于 2025-04-17 04:38

我在计算一个数的余弦值时,得到的结果有点不一样。请问我怎么能检查这个差异是否在机器精度范围内呢?

import math
math.cos(60.0/180.0*math.pi)
-> 0.5000000000000001

import numpy
numpy.cos(60.0/180.0*numpy.pi)
-> 0.50000000000000011

3 个回答

3

虽然你的数字最后看起来是相等的,但了解如何以完整的精度来检查它们仍然很有用。下面有几种方法可以做到这一点:

>>> a = 1.1 + 2.2
>>> b = 3.3
>>> a == b
False
>>> from decimal import Decimal
>>> Decimal.from_float(a)
Decimal('3.300000000000000266453525910037569701671600341796875')
>>> Decimal.from_float(b)
Decimal('3.29999999999999982236431605997495353221893310546875')
>>> a.hex()
'0x1.a666666666667p+1'
>>> b.hex()
'0x1.a666666666666p+1'
>>> a.as_integer_ratio()
(7430939385161319, 2251799813685248)
>>> b.as_integer_ratio()
(3715469692580659, 1125899906842624)
5

双精度运算可以提供15到16位小数的精确度。这两个值在这个精度范围内是一致的,所以不用担心。

我提到的小数是为了和双精度值的二进制表示中用于有效数字的53个二进制位区分开来。

16

这个区别似乎只是因为格式化的方式不同:

>>> '%.30f' % math.cos(60./180.*math.pi)
'0.500000000000000111022302462516'
>>> '%.30f' % np.cos(60./180.*np.pi)
'0.500000000000000111022302462516'

注意,np.cos 返回的是 np.float64 而不是 float,而且这两种类型在默认情况下的显示方式也不一样。在常见的硬件上,它们都是以 64 位的 double 来实现的,所以在精度上其实没有什么实际的区别。

撰写回答