使用 import numpy as np
时,我注意到
np.tan(np.pi/2)
提供标题中的数字而不是 np.inf
16331239353195370.0
我对这个数字很好奇。它是否与某些系统机器精度参数有关?我能从什么地方计算它吗?(我在思考类似于 sys.float_info
的内容)
编辑:相同的结果确实可以在其他环境中再现,如Java、Octave、Matlab...但建议的重复问题并没有解释为什么。
使用 import numpy as np
时,我注意到
np.tan(np.pi/2)
提供标题中的数字而不是 np.inf
16331239353195370.0
我对这个数字很好奇。它是否与某些系统机器精度参数有关?我能从什么地方计算它吗?(我在思考类似于 sys.float_info
的内容)
编辑:相同的结果确实可以在其他环境中再现,如Java、Octave、Matlab...但建议的重复问题并没有解释为什么。
pi
无法被Python浮点类型(同平台C的double
类型)准确表示。使用最接近可表示的近似值。
这是我电脑上使用的精确近似值(可能与您的电脑相同):
>>> import math
>>> (math.pi / 2).as_integer_ratio()
(884279719003555, 562949953421312)
为了找到这个比值的正切,我现在要切换到wxMaxima:(%i1) fpprec: 32;
(%o1) 32
(%i2) tan(bfloat(884279719003555) / 562949953421312);
(%o2) 1.6331239353195369755967737041529b16
基本上与您获得的相同。 使用的 pi / 2
的二进制近似值略小于 pi / 2
的数学(“无限精度”)值。 因此,您将获得非常大的正切值而不是无穷大
。 计算出的 tan()
适用于实际输入!
出于完全相同的原因,例如,
>>> math.sin(math.pi)
1.2246467991473532e-16
不返回0。近似值math.pi
略小于pi
,并且显示的结果是正确的,在那个条件下。
有几种方法可以看到使用的精确近似值:
>>> import math
>>> math.pi.as_integer_ratio()
(884279719003555, 281474976710656)
math.pi
的值完全等于该比率的数学(“无限精度”)值。
或者是以十六进制表示的精确浮点数:
>>> math.pi.hex()
'0x1.921fb54442d18p+1'
或者用几乎所有人都能理解的方式来说:
>>> import decimal
>>> decimal.Decimal(math.pi)
Decimal('3.141592653589793115997963468544185161590576171875')
虽然可能不是显而易见的,但是每个有限的二进制浮点数都可以精确地表示为有限的十进制浮点数(反之则不成立; 例如,十进制数0.1
不能精确地表示为有限的二进制浮点数),Decimal(some_float)
构造函数会生成精确等价物。
这里是pi
的真实值,后面跟着math.pi
的精确十进制值,并且第三行上的插入符号指向它们首次不同的数字:
true 3.14159265358979323846264338327950288419716939937510...
math.pi 3.141592653589793115997963468544185161590576171875
^
math.pi
现在在几乎所有的计算机上都相同,因为几乎所有的计算机都使用相同的二进制浮点数格式(IEEE 754双精度)。您可以使用上述任何一种方法来确认您的计算机上是否如此,或者如果您的计算机是例外情况,则可以找到正在使用的精确近似值。
np.pi
的表示是最接近系统 epsilon 的有理表示? - Aguynp.pi
与Python的math.pi
具有相同的值(我没有检查,但您可以检查;-)),那么它是该平台本地C double
浮点格式中可表示的最接近数学π的值。这意味着几乎所有现在的计算机都使用IEEE 754双精度浮点数,因此其最接近的二进制浮点数具有53位(尾数)精度。因此,有理数集被限制为形式为+/- I * 2 ** J
的形式,其中整数I
为0或2 ** 52 <= I <2 ** 53
,整数J
的范围足够广泛,可以覆盖所有接近pi
的此类有理数。 - Tim Petersnp.pi
,而不是 math.pi
。 - EKonsmath.pi
,np.pi
和scipy.pi
都相同;它们只是为了方便命名而重复。https://dev59.com/f2cs5IYBdhLWcg3wtmED - Tim Peters
np.inf
。但是,不仅可以简单地解释为什么它不是,还可以解释为什么答案恰好是所看到的 - 所以我这样做了;-) - Tim Peters