+1 Daumen
511 Aufrufe

Frage:

Ich soll in Python ein Programm schreiben, welches die positive Nullstelle von cos(x) im Intervall [0,2] annähert. Diese ist ja bekanntlich Pi/2. Bei dem Programm das ich geschrieben habe, bleibt die Zahl jedoch irgendwann gleich und nähert sich der gesuchten Zahl nicht weiter an. Ich soll die Zahl auf eine Genauigkeit von 50 Nachkommastellen annähern und dann am Ende noch als Dezimalbruch angeben.

Mein Programm:

from fractions import Fraction import math import decimal
decimal.getcontext().prec=50
def annäherung_Nullstelle_cos():
a_n = math.pi
b_n = 0

for i in range(0,60):
c = (decimal.Decimal(a_n) + decimal.Decimal(b_n))/decimal.Decimal(2.0)
  print(i, a_n, b_n, c, math.cos(c))
  print()

if (math.cos(c)) < 0:
    a_n = c
elif (math.cos(c)) > 0:
    b_n = c

print(Fraction.from_decimal(decimal.Decimal(a_n)))

Das Hauptproblem ist eigentlich folgendes:

Zahl die vom Programm ausgegeben wird:
1.5707963267948966724446668251803223211684205202832

Zahl die gesucht wird:
1.5707963267948965579989817342720925807952880859375

Avatar von

1 Antwort

+1 Daumen
 
Beste Antwort

Hallo,

ich bin in Python nicht bewandert, aber ich würde drauf wetten, dass in der Form wie oben codiert auch Python nicht in der Lage ist, den Cosinus auf 50 Stellen zu berechnen. Das führt dann dazu, dass irgendwann das \(\cos(c)\) immer den gleichen Wert liefert.

Du stellst die 50 Stellen am Objekt decimal ein, rechnest den Cosinus aber mit math aus. Woher soll math wissen, dass es auf 50 Stellen rechnen soll. Abgesehen davon wäre der Aufwand auch nicht ohne.

Poste doch mal die letzten 10 von den 60 Zeilen der Ausgabe. Möglichst auf 18 Stellen genau. Dann sollte sichtbar sein, was dort passiert.

Gruß Werner

Avatar von

Hey Werner-Salomon,

danke für deine Antwort, mit einer Genauigkeit von 18 Stellen sehen die letzten 10 Zeilen wie folgt aus:


50 1.57079632679489935 1.57079632679489656 1.57079632679489796 -1.2710352895928203e-15

51 1.57079632679489796 1.57079632679489656 1.57079632679489726 -6.049014748177263e-16

52 1.57079632679489726 1.57079632679489656 1.57079632679489691 -3.8285686989269494e-16

53 1.57079632679489691 1.57079632679489656 1.57079632679489674 -1.6081226496766366e-16

54 1.57079632679489674 1.57079632679489656 1.57079632679489665 6.123233995736766e-17

55 1.57079632679489674 1.57079632679489665 1.57079632679489670 -1.6081226496766366e-16

56 1.57079632679489670 1.57079632679489665 1.57079632679489668 -1.6081226496766366e-16

57 1.57079632679489668 1.57079632679489665 1.57079632679489666 6.123233995736766e-17

58 1.57079632679489668 1.57079632679489666 1.57079632679489667 -1.6081226496766366e-16

59 1.57079632679489667 1.57079632679489666 1.57079632679489666 6.123233995736766e-17

Ja - das ist wie schon vermutet. Ab \(i=53\) liefert \(\cos(c)\) nur noch zwei unterschiedliche Werte.

-1.6081226496766366e-16 und 6.123233995736766e-17 

Und auf Grund der fehlenden Genauigkeit, wird das auch nicht mehr besser. Das sind exakt die Werte, die ich bei einer CPU mit einer Fließkommadarstellung nach IEEE-754 mit 64Bit erwarten würde.

Es gibt sozusagen keinen Zahlenwert dazwischen, der als Ergebnis eines Cosinus-Aufrufs dargestellt werden kann.

Erkundige Dich mal, ob es irgendeine Möglichkeit gibt, die Genauigkeit bei der Cosinus-Berechnung zu erhöhen. Ich wüsste keine :-/

Alternativ kannst Du versuchen, \(\pi/2\) bzw. \(\pi\) zu berechnen - ohne den Cosinus zu nutzen! Die Bailey-Borwein-Plouffe-Formel benötigt nur die Grundrechenarten. Das sollte mit dem decimal-Objekt zu machen sein.

Das Problem ist halt, das ich nicht einfach so Pi/2 berechnen kann, wir sollen es mithilfe von dem Verfahren das ich im Programm benutze approximieren

Das Problem ist halt, das ich nicht einfach so Pi/2 berechnen kann, wir sollen es mithilfe von dem Verfahren das ich im Programm benutze approximieren

Wenn Cosinus plus 50Stellen vorgegeben ist, musst Du Dir eine Cosinus-Funktion suchen, die das kann. Oder den Cosinus selbst implementieren ... letzteres empfehle ich Dir nicht!

So eine Cosinus Funktion zu finden ist aber auch nicht so einfach :( Trotzdem danke für deine Hilfe

Ein anderes Problem?

Stell deine Frage

Willkommen bei der Stacklounge! Stell deine Frage einfach und kostenlos

x
Made by a lovely community