Agu*_*guy 87 python numpy numerical-methods
使用import numpy as np
我已经注意到了
np.tan(np.pi/2)
Run Code Online (Sandbox Code Playgroud)
给出标题中的数字而不是 np.inf
16331239353195370.0
Run Code Online (Sandbox Code Playgroud)
我很好奇这个号码.它与某些系统机器精度参数有关吗?我能用某些东西计算出来吗?(我正在思考类似的事情sys.float_info
)
编辑:相同的结果确实可以在其他环境中重现,如Java,octace,matlab ......但是建议的欺骗并不能解释原因.
Tim*_*ers 117
pi
并不像Python float那样完全可以表示(与平台C的double
类型相同).使用最接近的可表示近似值.
这是我的盒子上使用的精确近似值(可能与你的盒子上的相同):
>>> import math
>>> (math.pi / 2).as_integer_ratio()
(884279719003555, 562949953421312)
Run Code Online (Sandbox Code Playgroud)
要找到该比率的正切值,我现在将切换到wxMaxima:
(%i1) fpprec: 32;
(%o1) 32
(%i2) tan(bfloat(884279719003555) / 562949953421312);
(%o2) 1.6331239353195369755967737041529b16
Run Code Online (Sandbox Code Playgroud)
所以基本上与你得到的相同.使用的二进制近似值pi/2
略小于数学("无限精度")值pi/2
.所以你得到一个非常大的切线而不是infinity
.计算出来tan()
适合实际输入!
出于完全相同的原因,例如,
>>> math.sin(math.pi)
1.2246467991473532e-16
Run Code Online (Sandbox Code Playgroud)
不返回0近似math.pi
是小于一点点pi
,并且显示的结果是正确的给定真理.
有几种方法可以看到使用中的精确近似值:
>>> import math
>>> math.pi.as_integer_ratio()
(884279719003555, 281474976710656)
Run Code Online (Sandbox Code Playgroud)
math.pi
完全等于该比率的数学("无限精度")值.
或者作为十六进制表示法的精确浮点数:
>>> math.pi.hex()
'0x1.921fb54442d18p+1'
Run Code Online (Sandbox Code Playgroud)
或者以几乎每个人最容易理解的方式:
>>> import decimal
>>> decimal.Decimal(math.pi)
Decimal('3.141592653589793115997963468544185161590576171875')
Run Code Online (Sandbox Code Playgroud)
虽然它可能不是很明显,但每个有限二进制浮点数都可以精确表示为有限的十进制浮点数(反之则不正确;例如,十进制数0.1
不能完全表示为有限二进制浮点数),Decimal(some_float)
构造函数会生成精确的等效值.
这是真正的值,pi
后跟精确的十进制值math.pi
,第三行的插入符号指向它们不同的第一个数字:
true 3.14159265358979323846264338327950288419716939937510...
math.pi 3.141592653589793115997963468544185161590576171875
^
Run Code Online (Sandbox Code Playgroud)
math.pi
现在几乎所有的盒子都是相同的,因为现在几乎所有盒子都使用相同的二进制浮点格式(IEEE 754双精度).你可以使用任何方式上面,以确认在你的箱子,或者找到使用精确的近似,如果你的盒子是个例外.