使用import numpy as np
我注意到
np.tan(np.pi/2)
在标题中给出数字而不是 np.inf
16331239353195370.0
我很好奇这个数字。它与某些系统机器精度参数有关吗?我可以用某些东西计算出来吗?(我正在考虑类似的内容sys.float_info
)
编辑:在其他环境(例如Java,octace,matlab)中,相同的结果的确可以重现。
使用import numpy as np
我注意到
np.tan(np.pi/2)
在标题中给出数字而不是 np.inf
16331239353195370.0
我很好奇这个数字。它与某些系统机器精度参数有关吗?我可以用某些东西计算出来吗?(我正在考虑类似的内容sys.float_info
)
编辑:在其他环境(例如Java,octace,matlab)中,相同的结果的确可以重现。
np.inf
。但是,不仅要解释为什么不这样做,而且还要解释为什么答案正是所见到的东西,所以很简单-所以我做到了;-)
Answers:
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
,并且给出的真相显示的结果是正确的。
有几种方法可以查看使用中的精确近似值:
>>> 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中最接近的理性表示形式?
np.pi
具有与Python相同的值math.pi
(我没有检查,但您可以;-)),它是最接近平台本地C double
浮点格式可表示的数学pi的值。这意味着现在几乎所有盒子上都具有IEEE 754双精度,因此最接近的二进制浮点数具有53位(尾数)精度。因此有理数集被限制为+/- I * 2**J
整数I
为0或的形式,整数2**52 <= I < 2**53
的范围J
足够宽,可以覆盖该形式的所有有理数pi
。
np.pi
不是进口的math.pi
。
math.pi
,np.pi
和scipy.pi
都是相同的; 它们只是为了方便命名而被复制;stackoverflow.com/questions/12645547/...