Неожиданные результаты с десятичным делением в Python 2

Я пытаюсь сделать расчет

формула

Использование десятичного модуля python со следующим кодом:

from decimal import *
getcontext().prec = 9
sum = Decimal(0)
for i in range(1,11):
    sum += Decimal(1/(i**4))
print sum

однако это выводит 1, а не очень маленькую долю, как я ожидал. Я не могу найти здесь много информации https://docs.python.org/2/library/decimal.html о том, что не так с кодом. Я предполагаю, что сумма не используется в качестве десятичного числа в цикле, но я не уверен, как это решить.


person kalenpw    schedule 14.10.2016    source источник
comment
Если вы используете код из учебника Python 3 в Python 2, просмотрите любую статью о ключевых различиях. Раздел Что нового в Python 3.0 или любой другой. Знание различий заранее сэкономит вам часы головной боли ...   -  person smci    schedule 14.10.2016


Ответы (2)


Прежде всего, не используйте sum в качестве имени переменной, так как это встроенная функция.
И это необходимо для предоставления хотя бы одного числа с плавающей запятой для арифметики, если вы ожидаете ответа типа с плавающей запятой, здесь:

s = Decimal(0)

for i in range(1,11):
  s += Decimal(1./(i**4)) # dividing 1. or 1.0 instead of just 1
print s

это дает:

1.08203658
person lycuid    schedule 14.10.2016
comment
Ах, спасибо, что помогли. Не знал о сумме или о необходимости включения числа с плавающей запятой. Спасибо за быстрый ответ, приму через 7 минут - person kalenpw; 14.10.2016
comment
@kalenpw: обратите внимание, что даже в этом случае вы не получаете полной точности типа Decimal, поскольку вы только конвертируете float в Decimal (после вычисления). Если вам нужна высокая точность, вам нужно сделать s += Decimal(1)/Decimal(i**4). - person Tim Pietzcker; 14.10.2016

Если вы используете Python 2.x, то в выражении: 1/(i**4) используется целочисленное деление, в результате для i=1 оно равно 1, а для всех остальных i>1 - 0.

Просто добавьте плавающую точку к 1: 1./(i**4), это должно решить проблему.

PS В Python 3.x ваш код должен работать, как ожидалось, потому что оператор / определен для чисел с плавающей запятой, а оператор // определен для целых чисел.

person Slava    schedule 14.10.2016
comment
Да, это было сделано в 2.7, я должен был включить это в вопрос. Спасибо за лакомый кусочек работы в 3, мне придется чаще использовать 3. - person kalenpw; 14.10.2016