Seite 1 von 1

Pi mit Vieta bestimmen, Problem mit Decimal und Abbruchbedingung

Verfasst: Montag 13. Juni 2022, 08:58
von PatrickF
Hallo zusammen,

mit folgendem Skript möchte ich die Konvergenz der Pi-Bestimmung nach Vieta untersuchen, indem ich mich x Stellen an Pi annähere:

Code: Alles auswählen

#https://de.wikipedia.org/wiki/Vietas_Produktdarstellung_der_Kreiszahl_Pi
from decimal import Decimal, getcontext
# pi_10=Decimal(3.1415926535)
pi_30=Decimal(3.141592653589793238462643383279)
getcontext().prec = 31

p = Decimal(1)

c = Decimal(2).sqrt()

i=1

while True:
    p = Decimal(p * (c / 2))
    c = Decimal(2 + c).sqrt()
    print(i,Decimal(2/p))
    i=i+1
    if Decimal(2/p)==Decimal(pi_30):
        break
print()

print("Pi with 30 digits:", Decimal(pi_30))
print("Result Vieta: ",Decimal(2/p))
Aktuell habe ich zwei Baustellen:

1. Wie kann ich die Abbruchbedingung richtig gestalten? Aktuell läuft die Schleife endlos durch.
2. Warum wird mir bei der vorletzen Zeile nicht meine Variable pi_30 ausgegeben, sondern eine viel längere Zahl?

Über Tipps freue ich mich,
pf

Re: Pi mit Vieta bestimmen, Problem mit Decimal und Abbruchbedingung

Verfasst: Montag 13. Juni 2022, 09:14
von __blackjack__
@PatrickF: Ad 1.: Abbruchbedingung auf ``==`` ist halt nur wahr wenn die wirklich exakt gleich sind. Du musst schauen ob Du nah genug dran bist.

Ad 2.: Da wird Deine Variable pi_30 ausgegeben:

Code: Alles auswählen

In [42]: Decimal(3.141592653589793238462643383279)                              
Out[42]: Decimal('3.141592653589793115997963468544185161590576171875')
Du übergibst `Decimal` eine Gleitkommazahl, die nicht das ist was Du da hinschreibst, weil die halt nicht exakt gespeichert werden kann:

Code: Alles auswählen

In [46]: f"{3.141592653589793238462643383279:.60f}"                             
Out[46]: '3.141592653589793115997963468544185161590576171875000000000000'
Edit: Da sind ein paar überflüssige `Decimal`-Aufrufe im Code.

Code: Alles auswählen

#!/usr/bin/env python3
# https://de.wikipedia.org/wiki/Vietas_Produktdarstellung_der_Kreiszahl_Pi
from decimal import Decimal, localcontext
from itertools import count


def main():
    pi_30 = Decimal("3.141592653589793238462643383279")
    with localcontext() as context:
        context.prec = len(str(pi_30))

        p = Decimal(1)
        c = Decimal(2).sqrt()
        for i in count(1):
            p *= c / 2
            c = (2 + c).sqrt()
            print(i, 2 / p)
            if str(2 / p).startswith(str(pi_30)):
                break
        print()
        print("Pi with 30 digits:", pi_30)
        print("     Result Vieta:", 2 / p)


if __name__ == "__main__":
    main()

Re: Pi mit Vieta bestimmen, Problem mit Decimal und Abbruchbedingung

Verfasst: Montag 13. Juni 2022, 12:39
von PatrickF
Vielen Dank für die elegante Lösung.

Habe mal wieder die "..." bei Decimal vergessen...mir ist auch noch nicht so ganz klar wann und wie oft man das Decimal(..) setzen muss, anscheinend ja nur einmal pro Variable.


startswith() war die Funktion die ich gesucht habe, und das man die Länge einer Zahl über die Umwandlung in einen String bekommt hatte ich auch nicht mehr auf dem Schirm.

Das einzige was mich noch stört ist dass hier

Code: Alles auswählen

print("     Result Vieta:", 2 / p)
eine Stelle mehr ausgedruckt wird als in der Vorgabe. Wenn ich

Code: Alles auswählen

print(format((2/p), '.30f') )
benutze wird aber gerundet. Denke das werde ich wohl noch lösen können.... :)