小数的Python算术

标签 python numerical

当我在 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

我知道 float 没有无限精度,但它应该能够处理像 1e-17 这样的“大”小数字,不是吗?

最佳答案

float 在 0 附近的精度高于在 1 附近的精度。

  • 在 0.0 和 0.1 之间有 4591870180066957722 个 float 。
  • 在 0.9 和 1.0 之间有 900719925474099 个 float ,到目前为止更少。

float 密度每隔一定时间减半,看起来像这样:

visualization of density of floats

这是 1. 之后的下一个 float ,方向是 0.:

>>> import math
>>> math.nextafter(1., 0.)
0.9999999999999999
>>> format(math.nextafter(1., 0.), ".32f")  # let's see more decimal places
'0.99999999999999988897769753748435'

1 - 10-17 的数学正确值是 0.99999999999999999(有 17 个 9),我称这个数字为 < em>n。与几乎所有数字一样,n 无法用 float 精确表示。

0.99999999999999999                    # n
0.00000000000000001                    # distance between n and 1, i.e. 10^-17
0.00000000000000010102230246251565...  # distance between n and nextafter(1., 0.)

所以你看,1 - 10-17nextafter(1., 0.) 大约 10 倍来自 1.。当表达式 1. - 1.e-17 由解释器计算,它返回最接近的结果,即 1.。返回任何其他 float 是没有意义的,这将离“真实”结果更远(请原谅双关语)。

注意: math.nextafter在 Python 3.9+ 中可用。在早期版本中,您可以类似地使用 numpy.nextafter

相关问题-> Increment a Python floating point value by the smallest possible amount

关于小数的Python算术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10555659/

相关文章:

python - 如何在 fork 进程中使用 ipdb.set_trace

Python 重新组合字典中的项目

floating-point - 二进制 float 的十进制精度

c++ - 无论是在 C++ 还是 C 中,相同的数字代码都会返回不同的输出

java - 数字列表数组

c++ - 当矩阵不是奇异时,lapack cgesv 出错

python - 使用 python dblquad 进行复平面中的区域积分

python - 以日期和第三个变量作为颜色的散点图

python - __init__ 以函数作为参数(使用 NetworkX)

python - 使用 Matplotlib.image 自定义颜色图