Informatiker Board (http://www.informatikerboard.de/board/index.php)
- Themengebiete (http://www.informatikerboard.de/board/board.php?boardid=1)
--- Praktische Informatik (http://www.informatikerboard.de/board/board.php?boardid=6)
---- Algorithmen (http://www.informatikerboard.de/board/board.php?boardid=17)
----- Annäherung der positiven Nullstelle von cos(x) im Intervall [0,2] mittels Python (http://www.informatikerboard.de/board/thread.php?threadid=4385)


Geschrieben von Der Ahnungslose D. am 06.07.2021 um 10:32:

  Annäherung der positiven Nullstelle von cos(x) im Intervall [0,2] mittels Python

Meine Frage:
Hey, 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.

Hoffe jemand von euch kann mir weiterhelfen.



Meine Ideen:
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)))



Geschrieben von as_string am 06.07.2021 um 13:46:

 

Ich glaube, ein Python Programm, bei dem die Formatierung verloren gegangen ist, ist ziemlich nutzlos. Probier mal, ob es besser wird, wenn Du den Text zwischen
[code]...[/code]
Tags packst.

Gruß
Marco



Geschrieben von Der Ahnungslose D. am 06.07.2021 um 14:04:

 

Hey as_string, hier nochmal das Programm in sauber.

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)))



Geschrieben von as_string am 08.07.2021 um 11:47:

 

Hey as_string, hier nochmal das Programm in sauber.
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
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)))


[as_string: ich hab noch die code-Tags außenrum gemacht, damit die Einrückungen auch erhalten bleiben.]



Geschrieben von as_string am 09.07.2021 um 12:13:

 

Vorweg: Ich habe keine Ahnung von Python!

Aber trotzdem hab ich mal gegooglet. Klar ist, dass die Präzision eines normalen double (ich schätze mal, dass Python double verwendet) nicht ausreicht. Die Verwendung von decimal bringt dabei aber auch nichts, weil die Rückgabe von math.cos() ja ein double ist. Also bist Du nach wie vor auf die Präzision des normalen double beschränkt.
Ich habe mal testweise einfach mpmath statt math verwendet. Außerdem überall dieses decimal-Zeug raus geschmissen. decimal bringt nur was (so wie ich das verstehe), wenn Du es komplett mit Dezimalbrüchen zu tun hast und dabei Rundungsfehler vermeiden willst. Z. B. in Finanz-Anwendungen, wo alles so wie so auf Dezimalstellen gerundet werden muss, würden Fehler rein kommen, wenn Du auf 2-er Potenz gerundete Werte verwendest. Aber bei Kosinus/Sinus, etc. ist eine dezimal-Rundung ja genau so richtig oder falsch, wie eine im Dual-System. Da gewinnst Du keine Präzision.
Deshalb brauchst Du eine Zahlen-Darstellung mit höherer Präzision und die liefert offenbar das mpmath Paket, das auch cos() mit der höheren Präzision mitbringt.

Dann noch was mit dem Dezimal-Bruch. Normalerweise ist ein Dezimalbruch einfach die Darstellung mit 1,57... etc. Dann halt mit 50 Stellen. Du versuchst aber einen echten Bruch, was in meinen Augen nicht darunter zu verstehen wäre.

Ich hab mich jetzt trotzdem mal damit probiert (wie gesagt: Ich kann kein Python!) und hab das so zum Laufen gebraucht:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
from fractions import Fraction
from mpmath import *

mp.dps = 51
def annäherung_Nullstelle_cos():

     a_n = pi 

     b_n = mpf(0)

     for i in range(0,60): 
         
          c = (a_n + b_n)/mpf(2) 

          print(i, a_n, b_n, c, cos(c))
          print() 

          if (cos(c)) < 0: 
      
             a_n = c 

          elif (cos(c)) > 0: 

               b_n = c 

     nprint(c, 50)
     nprint(pi/mpf(2), 50)

annäherung_Nullstelle_cos()


Dabei habe ich pi-Halbe noch einmal das in mpmath fest verdrahtete ausgegeben. Wenn man statt 60 einfach mal 100 Schleifen-Durchläufe macht, sieht man, dass noch deutlich mehr Dezimalstellen sich dem Wert nähern, als noch nach 60 Durchläufen.

Gruß
Marco


Forensoftware: Burning Board, entwickelt von WoltLab GmbH