首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >大浮点数-精度误差

大浮点数-精度误差
EN

Stack Overflow用户
提问于 2015-06-21 10:01:16
回答 1查看 657关注 0票数 1

我试图在python2.7中使用Bigfloat库。

代码语言:javascript
运行
复制
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计算这个精度不可能吗?这是库中的错误吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-21 13:00:15

举个例子,下面是如何使用f1库将bigfloat计算得精确到256位。

代码语言:javascript
运行
复制
>>> 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最接近的二进制浮点数。这与BigFloat(1e-19)不同(没有单引号),因为1e-19是Python,因此已经舍入到53位精度。

有关更多细节,请查看文档

然而,有了一点创造力和代数,你根本不需要一个高精度的库。您可以将f1的表达式重写为:

代码语言:javascript
运行
复制
f1 = x * x * y * (1 / ((1 - z) * (1 - z)) - 1)

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

代码语言:javascript
运行
复制
f1 = x * x * y * (2-z) * z / ((1 - z) * (1 - z))

在这种形式下,当z非常小时,您不会失去准确性。所以现在常规的Python浮动已经足够好了:

代码语言:javascript
运行
复制
>>> 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库,但是维护得更好。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30963288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档