Почему вычисление значения числа пи с использованием формулы Мачина дает неправильное значение?
Для моего школьного проекта я пытался вычислить ценность использования различных методов. Одна из формул, которую я нашел, была Формула Мачина, которую можно вычислить, используя разложение Тейлора арктана (x).
Я написал следующий код на Python:
import decimal
count = pi = a = b = c = d = val1 = val2 = decimal.Decimal(0) #Initializing the variables
decimal.getcontext().prec = 25 #Setting percision
while (decimal.Decimal(count) <= decimal.Decimal(100)):
a = pow(decimal.Decimal(-1), decimal.Decimal(count))
b = ((decimal.Decimal(2) * decimal.Decimal(count)) + decimal.Decimal(1))
c = pow(decimal.Decimal(1/5), decimal.Decimal(b))
d = (decimal.Decimal(a) / decimal.Decimal(b)) * decimal.Decimal(c)
val1 = decimal.Decimal(val1) + decimal.Decimal(d)
count = decimal.Decimal(count) + decimal.Decimal(1)
#The series has been divided into multiple small parts to reduce confusion
count = a = b = c = d = decimal.Decimal(0) #Resetting the variables
while (decimal.Decimal(count) <= decimal.Decimal(10)):
a = pow(decimal.Decimal(-1), decimal.Decimal(count))
b = ((decimal.Decimal(2) * decimal.Decimal(count)) + decimal.Decimal(1))
c = pow(decimal.Decimal(1/239), decimal.Decimal(b))
d = (decimal.Decimal(a) / decimal.Decimal(b)) * decimal.Decimal(c)
val2 = decimal.Decimal(val2) + decimal.Decimal(d)
count = decimal.Decimal(count) + decimal.Decimal(1)
#The series has been divided into multiple small parts to reduce confusion
pi = (decimal.Decimal(16) * decimal.Decimal(val1)) - (decimal.Decimal(4) * decimal.Decimal(val2))
print(pi)
Проблема в том, что я получаю правильное значение числа Пи только до 15 знаков после запятой, независимо от того, сколько раз цикл повторяется.
Например:
на 11 повторений первого цикла
pi = 3,141592653589793408632493
при 100 повторениях первого цикла
pi = 3,141592653589793410703296
Я не увеличиваю количество повторений второго цикла, так как arctan(1/239) очень мала и достигает очень малого значения с несколькими повторениями, и поэтому не должна влиять на значение pi только в 15 десятичных разрядах.
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ:
Формула Мачина утверждает, что:
π = (16 * Summation of (((-1)^n) / 2n+1) * ((1/5)^(2n+1))) - (4 * Summation of (((-1)^n) / 2n+1) * ((1/239)^(2n+1)))
1 ответ
Этого количества терминов достаточно, чтобы получить более 50 знаков после запятой. Проблема заключается в том, что вы смешиваете поплавки Python с десятичными числами, поэтому ваши вычисления загрязняются ошибками в этих числах, которые имеют точность только до 53 бит (около 15 десятичных цифр).
Вы можете исправить это, изменив
c = pow(decimal.Decimal(1/5), decimal.Decimal(b))
в
c = pow(1 / decimal.Decimal(5), decimal.Decimal(b))
или же
c = pow(decimal.Decimal(5), decimal.Decimal(-b))
Очевидно, что аналогичное изменение должно быть сделано для
c = pow(decimal.Decimal(1/239), decimal.Decimal(b))
Вы могли бы сделать свой код намного более читабельным. Для начала вы должны поместить материал, вычисляющий ряд арктанов, в функцию, а не дублировать его для арктана (1/5) и арктана (1/239).
Кроме того, вам не нужно использовать десятичный для всего. Вы можете просто использовать простые числа Python для таких вещей, как count
а также a
, Например, ваш расчет для a
можно записать как
a = (-1) ** count
или вы могли бы просто установить a
1 за пределами цикла и отрицайте его каждый раз через цикл.
Вот более компактная версия вашего кода.
import decimal
decimal.getcontext().prec = 60 #Setting precision
def arccot(n, terms):
base = 1 / decimal.Decimal(n)
result = 0
sign = 1
for b in range(1, 2*terms, 2):
result += sign * (base ** b) / b
sign = -sign
return result
pi = 16 * arccot(5, 50) - 4 * arccot(239, 11)
print(pi)
выход
3.14159265358979323846264338327950288419716939937510582094048
Последние 4 цифры - мусор, а остальные в порядке.