3

I tried to compute math.exp(9500) but encountered an OverflowError: math range error (it's roughly 6.3e4125). From this question it seems like it's due to a too large float, the accepted answer says "(...) is slightly outside of the range of a double, so it causes an overflow".

I know that Python can deal with arbitrarily large integers (long type), is there a way to deal with arbitrarily large floats in the same manner ?

Edit : my original question was about using integers for calculating exp(n) but as Eric Duminil said, the simplest way to do that would be 3**n which doesn't provide any useful result. I know realize this question might be similar to this one.

potato
  • 169
  • 8
  • 1
    I'm afraid to even ask what kind of problem would require computing `exp(9500)`... – EOF Jul 25 '17 at 09:12
  • The problem itself doesn't but I'm doing matrix multiplications repeatedly : A * B, but B gets more sparse overtime, A remains constant. I was trying to calculate the number of multiplications needed depending on the variation of B's sparsity, in that case the number of "empty" lines of B was growing logarithmically from 1 to 9500 which gives us a total number of multiplications that looks a bit like "sum for i from 1 to n of (A-lines * B-columns * ln( (exp(9500)/n) * i )). – potato Jul 25 '17 at 09:22
  • 1
    In that case, you should probably just simplify the formula: `log((exp(9500)/n)*i)` is `9500 + log(i/n)`, or `9500 + log(i) - log(n)`. Then everything will work in normal double-precision floating-point. – Mark Dickinson Jul 25 '17 at 09:27
  • @MarkDickinson That's right ! I completely forgot to simplify that... I just tried it and Python doesn't complain anymore. Yet the same formula gives me 3.7323287594132553 * 10^9 with Python and 3.757328759413250...×10^9 with Wolfram Alpha. I'm wondering if that's just a rounding error ? – potato Jul 25 '17 at 10:02
  • @potato: Yes, it's just a rounding error. – Eric Duminil Jul 26 '17 at 07:38

3 Answers3

5

I don't think it's possible to approximate exp() with integers. If you use 3**n instead of 2.71828182845905**n, your calculations will be completely useless.

One possible solution would be to use Sympy. According to the documentation:

There is essentially no upper precision limit

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

You can also specify the desired precision:

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

With exp(9500).evalf(5000), you even get the integer closest to exp(9500).

Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
  • Thanks a lot, that's exactly what I was looking for. Also your solution provides much more and my question was probably not very well written, I re-wrote part of it to be more precise and explicit. – potato Jul 25 '17 at 09:03
3

Here's another way to calculate the result with Python:

exp(9500)

is too big.

But log10(exp(9500)) isn't. You cannot calculate it this way in Python, but log10(exp(9500)) is log(exp(9500))/ln(10), which is 9500/ln(10):

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

This way, you can calculate that exp(9500) is 6.27448493 * 10**4125 in plain Python, without any library!

Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
-2

try long type.

int type has been remove from python since 3.0 version.

Mojann
  • 1
  • 1
  • You should provide it in comments not in answer. Read the documentation pal @Mojann –  Jul 25 '17 at 07:34
  • This is incorrect - ```int``` is still here (though ```long``` is probably more appropriate for this problem.) https://docs.python.org/3/library/stdtypes.html – perigon Jul 25 '17 at 07:35
  • Im asking this question because the result of `math.exp` is a float. Python already implicitly converts `int` to `long` when needed. – potato Jul 25 '17 at 08:58