例如,以下是使用库计算f1
精度为 256 位的方法。bigfloat
>>> 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)
请注意使用,它以当前精度(256 位)BigFloat('1e-19')
创建最接近的二进制浮点数。10**-19
这与BigFloat(1e-19)
(没有单引号)不同,因为有1e-19
一个 Python 浮点数,所以已经四舍五入到 53 位精度。
查看文档以获取更多详细信息。
然而,有了一点创造力和代数,你根本不需要一个高精度的库。您可以将表达式重写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 浮点数已经足够好了:
>>> 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 库,但维护得更好。