当我在Python中使用小数字进行算术运算时,我得到以下意外结果:
>>> sys.float_info
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)
>>> (1. - (1.e-17) ) < 1.
False
Run Code Online (Sandbox Code Playgroud)
我知道浮点数不具有无限精度,但它应该能够处理像"1e-17"这样的"大"小数,不应该吗?
>>> import numpy as np
>>> np.nextafter(1., 0.)
0.99999999999999989
Run Code Online (Sandbox Code Playgroud)
这是继1.方向之后的下一个浮动0.
我想它比它1. - 1.e-17更接近,所以当评估时它会让你完全回来.使用更远的其他漂浮物是没有意义的. 1.numpy.nextafter(1., 0.)1. - 1.e-17
相关问题 - > 以尽可能小的量增加python浮点值
小智 6
首先,让我们回顾一下epsilon真的是在返回值sys.float_info。
Epsilon(或)是满足 0.5 + ? 0.5 和 0.5 - ? 0.5
Python 告诉您将导致0.5重复递增或递减的最小数字是epsilon=2.220446049250313e-16-但这仅适用于值 0.5。您正在尝试增加1.0的1.0e-17。这是一个更大的值(1.0 对 0.5),增加的数字比 0.5(1.0e-17 对 2.2e-16)更小。您大致偏离了一个数量级,因为 1.0e-17 的增量值比 1.0 的相对 epsilon 小一个数量级。
你可以在这里看到这个:
这些改变了价值 0.5
>>> 0.5+sys.float_info.epsilon
0.5000000000000002
>>> 0.5-sys.float_info.epsilon
0.4999999999999998
Run Code Online (Sandbox Code Playgroud)
这些值不会:
>>> 0.5+sys.float_info.epsilon/10.0
0.5
>>> 0.5-sys.float_info.epsilon/10.0
0.5
>>> 5.0+sys.float_info.epsilon
5.0
>>> 5.0-sys.float_info.epsilon
5.0
Run Code Online (Sandbox Code Playgroud)
解释:
IEEE 754定义了当今大多数标准计算机上使用的浮点格式(专业计算机或图书馆可能使用不同的格式。)IEEE 754的64 位格式使用 53 位精度来计算和 52 位存储到浮点数的尾数点值。由于您有一个固定的 52/53 位可以使用,尾数的大小和精度会随着值的增大/减小而变化。那么随着浮点数的相对大小的变化而变化。0.5 的值与 1.0 和 100.0 的值不同。
出于各种非常好的和特定于平台的原因(存储和表示、舍入等),即使您可以使用较小的数字,epsilon 也被定义为对 64 位浮点格式使用 52 位精度。由于大多数 Python 实现使用 C 双浮点数作为浮点数,因此可以证明:
>>> 2**-52==sys.float_info.epsilon
True
Run Code Online (Sandbox Code Playgroud)
查看您的平台将执行多少位:
>>> 0.5 + 2.0**-53
0.5000000000000001
>>> 0.5 - 2.0**-53
0.4999999999999999
>>> 0.5 + 2.0**-54
0.5 # fail for 0.5 + 54 bits...
>>> 0.5 - 2.0**-54
0.49999999999999994 # OK for minus
>>> 0.5 - 2.0**-55
0.5 # fail for 0.5 minus 55 bits...
Run Code Online (Sandbox Code Playgroud)
您的问题有几种解决方法:
nextafter. 更多关于nextafter我以前的回答在这里重要的概念是,的值是相对于值的(如果你是递增或递减)。
这可以在这里看到:
>>> numpy.nextafter(0.0,1.0)-0.0
4.9406564584124654e-324 # a relative epsilon value of 4.94e-324
>>> numpy.nextafter(0.01,1.0)-0.01
1.7347234759768071e-18 # 1e-17 would still work...
>>> numpy.nextafter(0.1,1.0)-0.1
1.3877787807814457e-17 # 1e-17 would >>barely<< work...
>>> numpy.nextafter(0.5,1.0)-0.5
1.1102230246251565e-16 # a relative epsilon value of 1.1e-16
>>> numpy.nextafter(500.0,501.0)-500.0
5.6843418860808015e-14 # relative epsilon of 5.6e-14
>>> numpy.nextafter(1e17,1e18)-1e17
16.0 # the other end of the spectrum...
Run Code Online (Sandbox Code Playgroud)
所以你可以看到 1e-17 可以轻松地增加 0.0 和 0.1 之间的值,但不会有太多大于这个的值。如上所示,1e17 的相对值是 16。
它应该能够处理像 1e-17 这样的“大”小数字,不是吗?
不一定(这取决于数字)。Afloat不能准确代表1e-17或1-(1e-17)。对于后者,它可以表示的最接近的数字是1。
我建议您阅读《每个计算机科学家应该了解的浮点运算》。
| 归档时间: |
|
| 查看次数: |
18394 次 |
| 最近记录: |