python - Bigfloat - 精度错误

标签 python python-2.7 floating-point bigfloat

我正在尝试在 python 2.7 中使用 Bigfloat 库。

from bigfloat import *

f1 = Context(precision=2000)

with precision(2000):  f1 = 1e-19*1e-19*9e9/((1-1e-18)*(1-1e-18))-1e-19*1e-19*9e9

with precision(100):  f2 = 1.6e-27*1.6e-27*6.6e-11/(1e-18*1e-18)

print BigFloat(f1) print f2

Python 给了我 f1=0,但这不是真的。我用g++测试了它,结果是1.75e-46

是我的程序出错了吗?是否无法使用 Bigfloat 计算此精度?是lib中的错误吗?

最佳答案

作为示例,以下是您如何使用 bigfloat 库将 f1 计算为 256 位精度。

>>> from bigfloat import BigFloat, precision
>>> with precision(256):
...     x = BigFloat('1e-19')
...     y = BigFloat('9e9')
...     z = BigFloat('1e-18')
...     f1 = x * x * y / ((1 - z) * (1 - z)) - x * x * y
... 
>>> f1
BigFloat.exact('1.800000000000000002700000000000000003600000000000000004500006811997284879750608e-46', precision=256)

请注意 BigFloat('1e-19') 的使用,它以当前精度(256 位)创建最接近 10**-19 的二进制 float )。这与 BigFloat(1e-19) (不带单引号)不同,因为 1e-19 是 Python float ,因此已四舍五入为 53 位精度。

看看documentation了解更多详情。

但是,只要有一点创造力和代数,您就根本不需要高精度库。您可以将 f1 的表达式重写为:

f1 = x * x * y * (1 / ((1 - z) * (1 - z)) - 1)

通过将所有内容放在一个公分母上,括号中的数量可以重写为 (2 - z) * z/((1 - z) * (1 - z))。因此,您同样可以将 f1 计算为:

f1 = x * x * y * (2-z) * z / ((1 - z) * (1 - z))

在这种形式中,当 z 非常小时,您不会失去准确性。所以现在常规的 Python float 就足够了:

>>> x = 1e-19
>>> y = 9e9
>>> z = 1e-18
>>> f1 = x * x * y * (2 - z) * z / ((1 - z) * (1 - z))
>>> f1
1.8e-46

如果您确实决定要使用高精度浮点库,我还建议您查看 gmpy2图书馆。它基于与 bigfloat 相同的底层 MPFR 库,但维护得更好。

关于python - Bigfloat - 精度错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30963288/

相关文章:

Swift:如何将字节转换为 float /获得更精确的数字?

python - pandas:四舍五入到用户定义的最接近的 float

python - 网页抓取错误: exceptions. MemoryError

python - 如何在pyqt中更改Qtablewidget的特定单元格背景颜色

python - Python `in` 与 `__contains__` 的功能

python - 如何在 python 中阅读?

python-2.7 - 根据一列值删除行

floating-point - Fortran 中具有 NaN 值的参数(常量)变量

python - 是否有理由从 Python 中的数字中减去零?

python - 将数组中的低值归零的最快方法?