Overflowerror: (34, 'Result Too Large')

OverflowError: (34, 'Result too large')

Python floats are neither arbitary precision nor of unlimited size. When k = 349, 16.**k is much too large - that's almost 2^1400. Fortunately, the decimal library allows arbitrary precision and can handle the size:

import decimal
decimal.getcontext().prec = 100
def pi():
pi = decimal.Decimal(0)
for k in range(350):
pi += (decimal.Decimal(4)/(decimal.Decimal(8)*decimal.Decimal(k+1))...)

OverflowError: (34, 'Result too large') in Python

Your exception comes from this line:

return (10**(lgn1 - (lgnk1 + lgk1)))

You tried to fix it by using Decimal like this:

return Decimal(10**(lgn1 - (lgnk1 + lgk1)))

But that won't help. Because lgn1, lgnk1, and lgk1 are float values, you're trying to do the arithmetic with float values, and then convert the result to a Decimal after it's done. Because the float arithmetic overflows, it never gets to the conversion.

What you need to do is make the arithmetic happen on Decimal values in the first place. For example:

lgn1 = Decimal(sum(math.log10(ii) for ii in range(1,ni)))
lgk1 = Decimal(sum(math.log10(ii) for ii in range(1,ki)))
lgnk1 = Decimal(sum(math.log10(ii) for ii in range(1,ni-ki+1)))

Now, when you do this:

return (10**(lgn1 - (lgnk1 + lgk1)))

… you've got Decimal arithmetic, not float, and it won't overflow (as long as your Decimal context is large enough for these numbers, of course).

But you probably want to push the Decimal as high up the chain as possible, not as low as possible. In this case, that's only one level up—calling math.log10 on an integer gives you a float, but calling the log10 method on a Decimal gives you a Decimal, so:

lgn1 = sum(Decimal(ii).log10() for ii in range(1, ni))

Meanwhile, for future reference:

I dont see how i can minimize this code further aside from erasing the lines of plotting.

Well, first, why not erase the lines of plotting then?

But, more importantly, you know that the exception happens on the last line of the logchoose function, and you know (or could know, by, say, adding a print ni, ki or running in the debugger) what arguments cause it to raise. So you could reduce the whole thing to the logchoose definition plus print logchoose(273, 114) (or whatever the arguments are).

Besides being a lot shorter, this would also completely take numpy and matplotlib out of the equation, so people who know nothing about those libraries but know a lot about Python (which is the vast majority, and includes people who are smarter than me, dbliss, and Nimrodshn, or at least smarter than me) could solve your problem.

OverflowError: (34, 'Result too large') on the resolution of a differential equation with Euler method

  • You are using an unknown or non-local array for the times, temps instead of liste_t

  • You are not implementing the Euler method Z = Z + pas*F(Z,liste_t[i-1]), you would have to employ some mechanism to implement the vector arithmetic, for instance

    Z = [ zk+pas*fk for zk, fk in zip(Z, F(Z,liste_t[i-1])) ]
  • You forgot to include the gravity force in the derivatives computation.


In general, the Euler method is only good to learn the principles of numerical ODE integration, for any useful result use a higher order method.

Error 34, Result too large

Well, first, let's split that big expression up into smaller ones, so we can see where it's going wrong. And use a debugger or some print statements to see what values are making it go wrong. That way, we're not just taking a stab in the dark.

If you do that, you can tell that (1+sqrt(5)**n_count) is raising this exception when n_count hits 605. Which you can verify pretty easily:

>>> (1+sqrt(5))**604
1.1237044275099689e+308
>>> (1+sqrt(5))**605
OverflowError: (34, 'Result too large')

So, why is that a problem?

Well, Python float values, unlike its integers, aren't arbitrary-sized, they can only hold what an IEEE double can hold:*

>>> 1e308
1e308
>>> 1e309
inf

So, the problem is that one of the terms in your equation is greater than the largest possible IEEE double.

That means you either need to pick a different algorithm,** or get a "big-float" library.

As it happens, Python has a built-in big-float library, in the decimal module. Of course as the name implies, it handles decimal floats, not binary floats, so you'll get different rounding errors if you use it. But you presumably don't care much about rounding errors, given your code.

So:

import decimal
s5 = decimal.Decimal(5).sqrt()

… then …

fib=int(((1+s5)**n_count-(1-s5)**n_count)/(2**n_count*s5))

* In fact, the limits are platform-specific; implementations aren't required to use IEEE doubles for float. So, use sys.float_info to see the max value for your platform. But it's almost always going to be 1.7976931348623157e+308.

** Note that the only advantage of the algorithm you're using over the naive one is that it allows you to approximate the Nth Fibonacci number directly, without calculating the preceding N-1. But since you want to print them all out anyway, you're not getting any advantage. You're just getting the disadvantages—it's an approximation; it's more complicated; it requires floating-point math, which is subject to rounding error; it's slower; it takes more memory; the built-in floating-point types in most languages on most platforms can't hold F(605), … All that for no benefit doesn't seem worth it.



Related Topics



Leave a reply



Submit