16331239353195370.0有特殊意义吗?

时间:2016-07-10 19:02:57

标签: python numpy numerical-methods

使用import numpy as np我注意到了

np.tan(np.pi/2)

给出标题中的数字,而不是np.inf

16331239353195370.0
我很好奇这个号码。它与某些系统机器精度参数有关吗?我能用某些东西计算出来吗? (我正在思考类似于sys.float_info

的内容

编辑:同样的结果确实可以在其他环境中重现,例如Java,octace,matlab ......但建议的欺骗并不能解释原因。

1 个答案:

答案 0 :(得分:117)

pi不能完全代表Python float(与平台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的数学(“无限精度”)值稍微小一些。所以你得到一个非常大的切线而不是infinity。计算出的tan()适合实际输入!

出于完全相同的原因,例如,

>>> math.sin(math.pi)
1.2246467991473532e-16

不返回0.近似值math.pi略小于pi,显示的结果是正确的给出真相。

其他寻找方法math.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双精度)。您可以使用上述任何方式在 框中确认,或者如果您的框是例外,则可以找到正在使用的精确近似值。