Вычислить число Пи в Python с помощью полигонов

У меня проблема с точным вычислением Пи. Я использую метод, в котором я получил круг с радиусом = 1, а внутри него я разместил многоугольники с 8, 16, 32, 64, ... углами, удваивая их после каждого шага. Но проблема в том, что правильными являются только первые 15 десятичных цифр результата.

Вот программа:

import math
import time
from decimal import *

n_Ecken = 8

while n_Ecken >=8:
    time.sleep(0.5)
    n_Ecken = n_Ecken * 2

    def berechneAlpha():
        kreis = 360                                                                 
        alphaInsideFunc = Decimal(kreis) / Decimal(n_Ecken)                         
        return alphaInsideFunc                                                      
    alphaOutsideFunc = berechneAlpha()


    def berechneBeta():                                                             
        betaInsideFunc = Decimal(alphaOutsideFunc) / Decimal(2)                      
        return betaInsideFunc                                                       
    betaOutsideFunc = berechneBeta()                                                


    def berechneKantenlaenge():                                                     
        Gegenkathete = Decimal(math.sin(math.radians(betaOutsideFunc)))             
        KantenlaengeInsideFunc = Gegenkathete * 2                                   
        return KantenlaengeInsideFunc                                               
    KantenlaengeOutsideFunc = berechneKantenlaenge()                                


    def berechneUmfang():                                                           
        UmfangInsideFunc = n_Ecken * KantenlaengeOutsideFunc                        
        return UmfangInsideFunc                                                     
    UmfangOutsideFunc = berechneUmfang()                                            


    def berechnePi():                                                               
        PiInsideFunc = UmfangOutsideFunc / 2                                        
        return PiInsideFunc                                                         

    getcontext().prec = 500
    print Decimal(berechnePi())
    print "Zahl der Ecken:", n_Ecken

Я надеюсь, вы понимаете это, потому что оно частично написано на немецком :D Все, что он делает, это берет восьмиугольник, делит 360° на количество углов (сначала 8), а затем на 2. Угол 22,5° — это результат, который программа теперь складывает в синус для вычисления 1/16 объема восьмиугольника, затем снова удваивает результат и умножает его на количество углов многоугольника. На последнем шаге (вверху ^^) он удваивает количество углов в многоугольнике и снова проходит все эти шаги.

Вот некоторые результаты первых нескольких шагов:

3.121445152258051969340613141
Zahl der Ecken: 16

3.1365484905459393161208936362527310848236083984375
Zahl der Ecken: 32

3.1403311569547529558121823356486856937408447265625
Zahl der Ecken: 64

3.14127725093277287982118650688789784908294677734375
Zahl der Ecken: 128

3.1415138011443008991818715003319084644317626953125
Zahl der Ecken: 256

3.141572940367091337776628279243595898151397705078125
Zahl der Ecken: 512

3.14158772527715957068039642763324081897735595703125
Zahl der Ecken: 1024

3.141591421511199744287523571983911097049713134765625
Zahl der Ecken: 2048

3.1415923455701175726062501780688762664794921875
Zahl der Ecken: 4096

3.14159257658487245379319574567489326000213623046875
Zahl der Ecken: 8192

3.141592634338562728402166612795554101467132568359375
Zahl der Ecken: 16384

3.141592648776985630121316717122681438922882080078125
Zahl der Ecken: 32768

3.14159265238659113350649931817315518856048583984375
Zahl der Ecken: 65536

3.14159265328899284241970235598273575305938720703125
Zahl der Ecken: 131072

3.1415926535145928255587932653725147247314453125
Zahl der Ecken: 262144

3.14159265357099304338817091775126755237579345703125
Zahl der Ecken: 524288

3.141592653585093319890120255877263844013214111328125
Zahl der Ecken: 1048576

3.14159265358861805594870020286180078983306884765625
Zahl der Ecken: 2097152

3.141592653589499573030252577154897153377532958984375
Zahl der Ecken: 4194304

3.141592653589719841278338208212517201900482177734375
Zahl der Ecken: 8388608

3.141592653589774908340359615976922214031219482421875
Zahl der Ecken: 16777216

3.14159265358978867510586496791802346706390380859375
Zahl der Ecken: 33554432

3.141592653589791783730333918356336653232574462890625
Zahl der Ecken: 67108864

3.141592653589792671908753618481568992137908935546875
Zahl der Ecken: 134217728

3.141592653589793115997963468544185161590576171875
Zahl der Ecken: 268435456

3.141592653589793115997963468544185161590576171875
Zahl der Ecken: 536870912

Последние 2 результата полностью равны и неверны. Это та часть, которая верна: 3.141592653589793, а остальная часть — нет. ПОЧЕМУ?

Обычно он повторял бы печать последней строки результата с большим количеством нулей в конце, потому что я установил «getcontext().prec = 500».

Что я сделал не так?

Я не очень разбираюсь в Python и программировании в целом. И, пожалуйста, не показывайте мне другие возможности для расчета, потому что это должен быть этот (для школы).

ОБНОВЛЕНИЕ: Проблема решена с помощью модуля mpmath. Ошибка заключалась в том, что встроенная функция math.sin() недостаточно точно вычисляла эти крошечные углы. Просто импортируйте «mpmath» вместо «math» и «decimal» и напишите mp.sin().


person Community    schedule 02.05.2015    source источник
comment
Потому что это ...115997963468544185161590576171875 не равно тому, что я нашел на каждой странице в Интернете, а в Pi не может быть одной и той же цифры рядом. И что вы имеете в виду под тем, что разница моих оценок уменьшается с каждым шагом? Что я также понял, так это то, что когда я использую math.pi для печати pi, это также неверно, когда говорят, что print Decimal(math.pi)   -  person    schedule 02.05.2015


Ответы (1)


Вы используете getcontext только для объектов Decimal, но при использовании традиционных математических функций вы теряете точность. Просто 64-битные числа с плавающей запятой дают точность 15–17 значащих десятичных цифр.
Возможно, вы можете попробовать использовать модуль sympy для большей точности по сравнению с символическими выражениями для вашего приближение.

person cosmoscalibur    schedule 02.05.2015
comment
Спасибо :) Я уже обнаружил это, но еще не пробовал. Что вы думаете о mpmath? - person ; 02.05.2015
comment
Просто mpmath используется для числовой оценки sympy (список модулей с SymPy). - person cosmoscalibur; 02.05.2015
comment
@holofox этот ответ был полезен для вас? - person cosmoscalibur; 10.05.2015
comment
Да спасибо. Я добавил раздел ОБНОВЛЕНИЕ по вопросу. Программа работает хорошо и быстро. - person ; 27.05.2015
comment
Извините, это был первый раз на SO :D - person ; 28.05.2015