I'm making a calculator in Python and am currently trying to prevent the program crashing when dealing with large input.
The only way I know how to catch errors is using 'try' and 'except', so I wrote this:
def solve(self, equation):
try:
return eval(equation)
except(OverflowError):
messagebox.showinfo("Error","Result too large")
return equation
(I'm aware eval
can be dangerous but the user is unable to type any input so I think it's fine)
When I input a massive number in scientific notation like '389e+10**(58)*9'
the OverflowError
is caught successfully, but if I put in something like '55555555**5555555'
the window stops responding.
I was under the impression the latter also raises an OverflowError
but I now I think this is could be happening because it doesn't create an error at all, and eval
just can't handle working out a result this large.
If this is the case, I think I should put a limit on how large the answer should be, but I'm unsure of how I would decide on this limit. Any suggestions?
In Python, float
is usually a 64-bit floating point number, which can hold a finite range. Values above that cause an OverflowError
to be raised. As 389e+10
returns a float
, the entire expression 389e+10**(58)*9
also returns a float
.
On the other hand, 55555555**5555555
returns an int
. In Python, int
can hold arbitrarily large values, limited only by memory. Therefore, what is happening is that Python attempts to calculate a really big number, taking a really, really long time to do so.
This is, in general, not that easy of a question to solve, because you're using eval
, and therefore you have no information about the exact nature of the equation.
I would suggest instead parsing the equation, which will allow you to inspect it in detail. You could then, among other things, not perform exponentiation calculations where both the base and exponent are large.
(or you could just use floating point calculation for everything, which will affect precision, but I don't think that really matters for a simple calculator, right?)