2015-08-03 5 views
1

Код дает ошибку, потому что значение «var» очень близко к нулю, меньше 1e-80. Я попытался исправить эту ошибку, используя «Import decimal *», но на самом деле это не работает. Есть ли способ сказать Python округлить число до нуля, когда число с плавающей точкой очень близко к нулю, т. Е. < 1e-50? Или любой другой способ исправить эту проблему?
Спасибо
КОДА:Python: ограничение на точность float

import math 
H=6.6260755e-27 
K=1.3807e-16 
C=2.9979E+10 
T=100.0 
x=3.07175e-05 

cst=2.0*H*H*(C**3.0)/(K*T*T*(x**6.0)) 
a=H*C/(K*T*x) 
var=cst*math.exp(a)/((math.exp(a)-1.0)**2.0) 
print var 

ВЫВОД:

Traceback (most recent call last): 
    File "test.py", line 11, in <module> 
    var=cst*math.exp(a)/((math.exp(a)-1.0)**2.0) 
OverflowError: (34, 'Numerical result out of range') 

Кевин: Код был отредактирован следующими строками:

from decimal import * 
getcontext().prec = 7 
cst=Decimal(2.0*H*H*(C**3.0)/(K*T*T*(x**6.0))) 
a=Decimal(H*C/(K*T*x)) 
+2

_ «Я попытался исправить эту ошибку, используя« Импортировать десятичное число », но на самом деле это не работает». _ Почему нет? Посмотрим код, где вы его попробовали. – Kevin

+2

* «Есть ли способ сказать Python округлить число до нуля, когда число с плавающей точкой очень близко к нулю, т.е. <1e-50?" * - 'num = 0, если abs (num-0) <1e-50 else num'? – jonrsharpe

+0

@jonrsharpe: программа должна сначала вычислить «var», чтобы использовать оператор «if». – Curiosity

ответ

1

Проблема заключается в том, что (math.exp(a)-1.0)**2.0 слишком большой для хранения в качестве промежуточного результата.

>>> (math.exp(a) - 1.0)**2.0 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
OverflowError: (34, 'Result too large') 

Однако, для значения a вы используете,

>>> math.exp(a)/(math.exp(a)-1.0) == 1.0 
True 

так что вы можете по существу отменить ту часть фракции, оставляя

var = cst/(math.exp(a)-1.0) 

который оценивает красиво

>>> cst/(math.exp(a)-1.0) 
7.932672271698049e-186 

Если вам неудобно переписывать формулу до такой степени, используйте ассоциативность операций, чтобы избежать большого промежуточного значения. Полученный продукт тот же.

>>> cst/(math.exp(a)-1.0)*math.exp(a)/(math.exp(a)-1.0) 
7.932672271698049e-186 
0

Я решил эту проблему, но это будет работать только для этой конкретной проблемы, а не в целом. Основной проблемой является характер этой функции:

math.exp(a)/(math.exp(a)-1.0)**2.0 

, который быстро распадается. Проблема может быть легко решена, ограничивая значение «a» (что не приведет к существенным изменениям в расчете). т. е.

if a>200: 
    var=0.0 
else: 
    var=cst*math.exp(a)/((math.exp(a)-1.0)**2.0) 
Смежные вопросы