Python:使用浮点数进行任意精度

3
我尝试计算math.exp(9500),但遇到了一个OverflowError: math range error(大约是6.3e4125)。从这个问题中可以看出,这似乎是由于浮点数过大而导致的,被接受的答案说:“(...)略微超出了double的范围,因此会引起溢出”。
我知道Python可以处理任意大的整数(长整型),是否有一种类似的方法来处理任意大的浮点数? 编辑:我的原始问题是关于使用整数计算exp(n),但正如Eric Duminil所说,最简单的方法是使用3**n,它并不提供任何有用的结果。我现在意识到这个问题可能类似于这个问题

1
我甚至不敢问什么样的问题需要计算 exp(9500)... - EOF
问题本身并不复杂,但我需要一遍又一遍地进行矩阵乘法运算:A * B,而B随着时间变得越来越稀疏,A保持恒定。我试图根据B的稀疏度变化来计算所需的乘法次数,在这种情况下,B的“空”行数从1增长到9500,这给我们带来了一个类似于“求和从1到n的(A行数B列数ln((exp(9500)/n)* i))”的总乘法次数。 - potato
1
在这种情况下,您应该简化公式:log((exp(9500)/n)*i) 等于 9500 + log(i/n) 或者 9500 + log(i) - log(n)。然后所有内容都将在正常的双精度浮点数中运行。 - Mark Dickinson
@MarkDickinson 没错!我完全忘记简化它了...我刚试了一下,Python不再抱怨了。 然而,同样的公式在Python中给出了3.7323287594132553 * 10^9,在Wolfram Alpha中给出了3.757328759413250...×10^9。我想知道这是否只是一个舍入误差? - potato
@potato:是的,这只是一个舍入误差。 - Eric Duminil
3个回答

5

我认为用整数来近似exp()是不可能的。如果你使用3**n来代替2.71828182845905**n,那么你的计算将完全无用。

一种可能的解决方案是使用Sympy。根据文档:

基本上没有上限精度

>>> from sympy import *
>>> exp(9500)
exp(9500)
>>> exp(9500).evalf()
6.27448493490172e+4125

您还可以指定所需的精度:

>>> exp(9500).evalf(1000)
6.274484934901720177929867046175406311474380389941415760684209191232450360090766458256588885184199320756050569665785657269735313171886975309933254563488343491718198237894473901620914303565550450204805537225888529509352754121292701357622411614860860409639719786022989336837263283678476008817556351031696366815467221836948040042378034720460820127399855873232167818091083005170669482845098735176209372328114732133251096196535355946589133977397512846130629857604295369747597459602137604440011394793443041829253598478244189078131130488653468669559814695095974271938947640276013215753183113041899037415404445478806695965167014404297848725756879184380559837391976534521522360723388582608454995349380217499779247330557664230806254642768796486899322646423713763772064068933790640394967085887914192401473425799354391464743910233873602389444180426155866237536459654917521713769608318128404177877383203786348495822099924812081683286880293701785567962687838594752986160305764297117036426951203418854463404773701882e+4125

使用 exp(9500).evalf(5000),你甚至可以得到最接近 exp(9500) 的整数。


非常感谢,这正是我在寻找的。此外,您的解决方案提供了更多内容,我的问题可能没有写得很好,我重新撰写了部分内容以使其更加精确和明确。 - potato

3
以下是使用Python计算结果的另一种方法:
exp(9500)

数字太大了。

但是log10(exp(9500))并不是。在Python中不能用这种方式计算它,但是log10(exp(9500))等于log(exp(9500))/ln(10),也就是9500/ln(10)

>>> from math import log
>>> 9500/log(10)
4125.797578080892
>>> int(9500/log(10))
4125
>>> 10**(9500/log(10) % 1)
6.274484934896202

这样,您可以在纯Python中计算exp(9500),不需要任何库,结果为6.27448493 * 10**4125


-2
尝试使用long类型。
自Python 3.0版本以来,int类型已被移除。

你应该在注释中提供它,而不是在答案中。阅读文档,伙计 @Mojann - user7571182
这是不正确的 - int 仍然存在(尽管对于这个问题,long 可能更合适)。https://docs.python.org/3/library/stdtypes.html - perigon
我提出这个问题是因为math.exp的结果是一个浮点数。当需要时,Python已经隐式地将int转换为long - potato

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接