16331239353195370.0有什么特殊意义吗?
Is there special significance to 16331239353195370.0?
使用 import numpy as np
我注意到
np.tan(np.pi/2)
给出标题中的数字而不是 np.inf
16331239353195370.0
我很好奇这个数字。是否与某些系统机器精度参数有关?我可以从某些东西中计算出来吗? (我的思路类似于 sys.float_info
)
编辑: 相同的结果确实可以在其他环境中重现,例如 Java、octace、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
的数学值 ("infinite precision")。所以你得到一个非常大的切线而不是 infinity
。计算出的 tan()
适合实际输入!
出于完全相同的原因,例如,
>>> math.sin(math.pi)
1.2246467991473532e-16
不return0。近似值math.pi
比pi
小一点,显示的结果是正确的given 那个道理。
其他观看方式math.pi
有几种方法可以查看正在使用的精确近似值:
>>> import math
>>> math.pi.as_integer_ratio()
(884279719003555, 281474976710656)
math.pi
正好等于该比率的数学 ("infinite precision") 值。
或者作为十六进制表示法中的精确浮点数:
>>> math.pi.hex()
'0x1.921fb54442d18p+1'
或者以几乎每个人都最容易理解的方式:
>>> import decimal
>>> decimal.Decimal(math.pi)
Decimal('3.141592653589793115997963468544185161590576171875')
虽然可能不是很明显,但每个有限二进制浮点数都可以精确地表示为有限十进制浮点数(反过来是 not true;例如十进制 0.1
不能完全表示为有限二进制浮点数),并且 Decimal(some_float)
构造函数产生完全等价的结果。
这是 pi
的真值,后面是 math.pi
的精确十进制值,第三行的插入符号指向它们不同的第一个数字:
true 3.14159265358979323846264338327950288419716939937510...
math.pi 3.141592653589793115997963468544185161590576171875
^
math.pi
现在在 "almost all" 个盒子中是一样的,因为现在几乎所有的盒子都使用相同的二进制浮点格式(IEEE 754 双精度)。您可以使用上述任何一种方式来确认 您的 框,或者如果您的框是一个例外,则可以找到正在使用的精确近似值。
使用 import numpy as np
我注意到
np.tan(np.pi/2)
给出标题中的数字而不是 np.inf
16331239353195370.0
我很好奇这个数字。是否与某些系统机器精度参数有关?我可以从某些东西中计算出来吗? (我的思路类似于 sys.float_info
)
编辑: 相同的结果确实可以在其他环境中重现,例如 Java、octace、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
的数学值 ("infinite precision")。所以你得到一个非常大的切线而不是 infinity
。计算出的 tan()
适合实际输入!
出于完全相同的原因,例如,
>>> math.sin(math.pi)
1.2246467991473532e-16
不return0。近似值math.pi
比pi
小一点,显示的结果是正确的given 那个道理。
其他观看方式math.pi
有几种方法可以查看正在使用的精确近似值:
>>> import math
>>> math.pi.as_integer_ratio()
(884279719003555, 281474976710656)
math.pi
正好等于该比率的数学 ("infinite precision") 值。
或者作为十六进制表示法中的精确浮点数:
>>> math.pi.hex()
'0x1.921fb54442d18p+1'
或者以几乎每个人都最容易理解的方式:
>>> import decimal
>>> decimal.Decimal(math.pi)
Decimal('3.141592653589793115997963468544185161590576171875')
虽然可能不是很明显,但每个有限二进制浮点数都可以精确地表示为有限十进制浮点数(反过来是 not true;例如十进制 0.1
不能完全表示为有限二进制浮点数),并且 Decimal(some_float)
构造函数产生完全等价的结果。
这是 pi
的真值,后面是 math.pi
的精确十进制值,第三行的插入符号指向它们不同的第一个数字:
true 3.14159265358979323846264338327950288419716939937510...
math.pi 3.141592653589793115997963468544185161590576171875
^
math.pi
现在在 "almost all" 个盒子中是一样的,因为现在几乎所有的盒子都使用相同的二进制浮点格式(IEEE 754 双精度)。您可以使用上述任何一种方式来确认 您的 框,或者如果您的框是一个例外,则可以找到正在使用的精确近似值。