我在python中写了一个简单的代码,使用numpy命令为我提供了与机器epsilon相同的值:np.finfo(float).eps代码为:
eps=1
while eps+1 != 1:
eps /= 2
print(eps)
但我不想停在这里!我用越来越小的数字来划分eps,例如:
eps=1
while eps+1 != 1:
eps /= 1.1
print (eps)
这样,我得到了ε的值1.158287085355336e-16。我注意到epsilon正在收敛为一个数字,我最后一次尝试1.0000001时得到了1.11022311190697707e-16的值。
这个值更接近我的Pc的ε的实际值吗?我认为我没有考虑重要的事情,我的思路是错误的。
提前感谢您的帮助!
术语"machine epsilon"的定义并不一致,因此最好避免使用该词,而是具体说明您正在谈论的内容:
-
ulp(1),1的最低有效位数或最后一位的单位的大小。这是从1到下一个较大浮点数的距离。更一般地说,ulp()是从到下一个较大浮点数的距离。
- 在二进制64浮点中,精度为53位,ulp(1)为2⁻⁵²≈2.220446049250313×10⁻cco⁶.
- 在十进制64浮点中,精度为16位,ulp(1)为10⁻cco⁵.
通常,对于具有精度数字(包括隐式1位)的基数中的浮点,ulp(1)=1−。
-
相对误差界,有时也称为单位舍入或u。浮点运算可以对数学函数(如+)的结果进行四舍五入,对于某些相对误差,给出fl(+)=(+)·(1+)。
对于IEEE 754(+,−,*,/,sqrt)中的基本算术运算,浮点运算的计算结果保证正确取整,在默认取整模式下,这意味着它产生最接近的浮点数,或者如果+正好位于浮点数的中间,则产生两个最接近的浮点数之一。
- 在精度为53位的二进制64浮点中,正确四舍五入到最近值的运算的相对误差最多为2⁻⁵³≈1.1102230246251565×10⁻cco⁶.
- 在精度为16位的十进制64浮点中,正确四舍五入到最近值的运算的相对误差最多为5×10⁻cco⁶.
通常,当以精度数字为基数的浮点运算被正确地四舍五入到最近值时,其大小受相对误差界(/2)−的限制。
Python迭代while 1 + eps != 1: eps /= 2
从eps = 1.
开始计算的是二进制64浮点中的相对误差界限,因为这是基本上所有Python实现都使用的浮点。
如果您有一个使用不同基数的Python版本,比如b
,那么您会希望使用while 1 + eps != 1: eps /= b
。如果你做eps /= 1.1
或eps /= 1.0001
,你会得到相对误差界的近似值,误差在较大的一侧,对结果没有特别的意义。
注意,sys.float_info.epsilon
是ulp(1),而不是相对误差界。它们总是相关的:ulp(1)/2是每个浮点格式中的相对误差界。
如果您希望实际机器epsilon用于PC上的Python浮点,可以从sys.float_info
的epsilon
属性中获取。顺便说一下,在我的x86-64机器上,numpy.finfo(float)
给了我2.220446049250313e-16
,这是64位浮点的预期机器ε。
您试图找到值eps
以使1 + eps != 1
为True
的直觉是好的,但由于浮点运算中的舍入,机器ε是相对误差的上界。更不用说,浮点运算的不精确性有时会让人感到困惑:请注意,0.1 + 0.1 + 0.1 != 0.3
的求值结果为True
。此外,如果我将您的代码修改为
eps = 1
while eps + 9 != 9:
eps = eps / 1.0000001
print(eps)
大约半分钟后,我得到
8.881783669690459e-16
这种情况下的相对误差为CCD_ 17。
您的程序几乎很好。
IT应该是
eps=1
while eps+1 != 1:
eps /= 2
print(2*eps)
结果是2.220446049250313e-16
这是机器的ε。你可以用这个来检查代码:
import sys
sys.float_info.epsilon
我们应该在最后一行乘以2的原因是,在while循环中,你把1除法做得太远了。