Как предотвратить ошибки с большими результатами при использовании eval ()? - PullRequest
2 голосов
/ 27 мая 2019

Я делаю калькулятор на Python и в настоящее время пытаюсь предотвратить сбой программы при работе с большим вводом.

Единственный способ, которым я знаю, как отлавливать ошибки, это использовать 'try' и 'кроме', поэтому я написал это:

def solve(self, equation):
    try:
        return eval(equation)
    except(OverflowError):
        messagebox.showinfo("Error","Result too large")
    return equation

(я знаю, eval может быть опасно, но пользователь не может набрать любой ввод, поэтому я думаю, что все в порядке)

Когда я вводю огромное число в научной нотации, например '389e+10**(58)*9', OverflowError успешно перехватывается, но если я добавляю что-то вроде '55555555**5555555', окно перестает отвечать.

У меня сложилось впечатление, что последний также поднимает OverflowError, но теперь я думаю, что это может произойти, потому что это вообще не создает ошибки, а eval просто не может справиться с обработкой результата. это большое.

Если это так, я думаю, что я должен наложить ограничение на то, насколько большим должен быть ответ, но я не уверен, как бы я принял решение по этому пределу. Есть предложения?

Ответы [ 2 ]

4 голосов
/ 27 мая 2019

В Python float обычно представляет собой 64-разрядное число с плавающей запятой, которое может содержать конечный диапазон. Значения выше этого вызывают повышение OverflowError. Поскольку 389e+10 возвращает float, все выражение 389e+10**(58)*9 также возвращает float.

С другой стороны, 55555555**5555555 возвращает int. В Python int может содержать произвольно большие значения, ограниченные только памятью. Поэтому происходит то, что Python пытается вычислить действительно большое число, и на это уходит очень много времени.

Как правило, этот вопрос не так легко решить, потому что вы используете eval, и, следовательно, у вас нет информации о точной природе уравнения.

Я бы предложил вместо этого проанализировать уравнение, которое позволит вам детально изучить его. Тогда вы могли бы, среди прочего, не выполнять вычисления возведения в степень, когда и база, и экспонента велики.

(или вы можете просто использовать вычисления с плавающей запятой для всего, что повлияет на точность, но я не думаю, что это действительно важно для простого калькулятора, верно?)

0 голосов
/ 27 мая 2019

Он перестает отвечать, потому что занят вычислением 55555555**5555555. Это не вызовет OverflowError, потому что целые числа в Python имеют произвольную точность. Он будет становиться все больше и больше, занимать все больше и больше памяти, пока не нанесет вред вашему компьютеру, что он и сделал.

...