Python: поплавок бесконечной длины (точный поплавок)

Мой код:

def calc_pi(acc):
     pos = False
     sum = 4.0
     for i in range(2, acc):
          if not pos:
               sum -= 4.0/(2*i-1)
               pos = True
          else:
               sum += 4.0/(2*i-1)
               pos = False
     return float(sum)

print(calc_pi(5000))

И, конечно же, я пытаюсь вычислить число пи с более чем 10 цифрами после запятой. Но Python, кажется, округляется до 10. Есть ли простой способ предотвратить это? Как миллион цифр после запятой?

Спасибо!


person d0n.key    schedule 04.07.2015    source источник
comment
может не принести вам миллион, но decimal может дать вам еще немало. (docs.python.org/2/library/decimal.html)   -  person NightShadeQueen    schedule 04.07.2015
comment
Кстати: используемый вами алгоритм очень медленный, и то, как вы его реализовали, приводит к дополнительной ошибке округления. Если вы хотите вычислить число пи самостоятельно, возможно, вы захотите изучить более совершенные алгоритмы.   -  person    schedule 04.07.2015
comment
@Hurkyl прав. Но, с другой стороны, выполнение этого в python требует гораздо больше накладных расходов, чем просто это - это может быть только доказательством концепции :)   -  person Marcus Müller    schedule 04.07.2015


Ответы (3)


Вы можете использовать класс Decimal, предоставляемый стандартной библиотекой.

Из документов:

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

  >>> from decimal import *
  >>> getcontext().prec = 6
  >>> Decimal(1) / Decimal(7)
  Decimal('0.142857')
  >>> getcontext().prec = 28
  >>> Decimal(1) / Decimal(7)
  Decimal('0.1428571428571428571428571429')
person musically_ut    schedule 04.07.2015

Вы можете использовать алгоритм Чудновского для вычисления 100 000 000 десятичных знаков числа π. См. также связанные вопросы 1000-digits-of-pi-in-python и вычисление python-pi.

Если вы не хотите реализовывать собственный алгоритм, вы можете использовать пакет mpmath. Примерно для 1000000 знаков после запятой с рядом Чудновского:

from mpmath import mp
mp.dps = 1000000  # number of digits
print(mp.pi)   # calculate pi to a million digits (takes ~10 seconds)
person s0nskar    schedule 04.07.2015

Встроенная плавающая точка Python обычно представляет собой 64-битное число с плавающей запятой IEEE754 (обычно называемое «двойным»).

То, что вам нужно, - это не представление с плавающей запятой, а на самом деле что-то расширяемое в (двоичных) цифрах, точно так же, как целочисленный тип python может расти произвольно.

Поэтому я призываю вас взглянуть на представление дробных целых чисел и выполнить математические вычисления, чтобы представить в нем ваше число.

person Marcus Müller    schedule 04.07.2015
comment
@rth: ну, плавающая запятая понадобится только в том случае, если показатель степени целого числа когда-либо изменится. Но все его итерации окажутся между 2 и 4, поэтому наличие числа с плавающей запятой просто тратит впустую все биты экспоненты. то, что расширяется с произвольной точностью fp, будет мантиссом, но если вы только когда-либо измените это, ваша мантисса станет представлением дробного числа :) - person Marcus Müller; 06.07.2015
comment
Верно, но тогда мантисса всегда является представлением дробного числа, поэтому, следуя этой логике, числа с плавающей запятой IEEE также не являются числами с плавающей запятой ^^. Я предполагаю, что это вопрос словарного запаса, независимо от того, имеют ли люди в виду числа с плавающей запятой числа с плавающей запятой IEEE или что-либо с мантиссом и показателем степени (с произвольным числом битов в каждом). - person rth; 06.07.2015
comment
@rth очень верно :) ты прав. Особенность этого случая в том, что показатель степени не изменится. - person Marcus Müller; 06.07.2015