|
Auf dieser Seite werden einige Algorithmen vorgestellt, welche die Berechnung von
Pi (π) mit Hilfe von Reihen-Algorithmen durchführen. Die Kreiszahl π stellt die Beziehung zwischen Radius und Fläche eines Kreises dar. Ihre Berechnung war während der gesamten kulturellen Geschichte eine wichtige Aufgabe der Wissenschaft. |
Die Seite hat hauptsächlich das Ziel, die Programmierung von Reihen-Entwicklungen
vorzustellen und praktisch auszuprobieren. In der Praxis ist es nur sehr selten notwendig, selbst die Zahl π zu berechnen. |
Algorithmen
|
Ausgewählte IT-Rezepte, Iterationen |
| Wozu Pi berechnen ? | Gute Trainings-Gelegenheit |
| Programmiersprachen | Verwendung von Pi in Programmiersprachen |
| Pi nach Viète 1593 | Maximale Genauigkeit (15 Stellen) in 20 µs |
| Pi nach Wallis 1655 | 6 Dezimalstellen in 150000 µs |
| Pi nach Leibnitz 1682 | 6 Dezimalstellen in 140000 µs |
| Pi nach Malcolm 1706 | Maximale Genauigkeit (15 Stellen) in 15 µs |
| Pi nach Euler, 1748 | 6 Dezimalstellen in 140000 µs oder Maximale Genauigkeit (15 Stellen) in 60000 µs |
| Pi nach BBP 1996 | Maximale Genauigkeit (15 Stellen) in 10 µs |
| Monte-Carlo | Berechnung der Kreiszahl durch oftmaliges Probieren |
| Verwandte Themen: | Reihen-Entwicklung von Winkelfunktionen (Sinus, Cosinus, Arcustangens) |
Wozu Pi berechnen ? |
|
| ▼ Die Beispiele dieser Seite haben wenig praktische Bedeutung, da man in eigenen Programmen kaum jemals die Berechnung der Kreiszahl Pi programmieren muss. | Das ↓ nächste Kapitel bietet eine Übersicht zur Verwendung von Pi in gängigen Programmiersprachen. |
Ausbildung und Training▲ Die Aufgabe hat sich jedoch für die Ausbildung als sehr brauchbar herausgestellt:• Alle Beispiele haben das gleiche, leicht zu kontrollierende Ziel, sind etwa gleich schwierig, und trainieren die gleichen Fähigkeiten der Programmierung. • Die Beispiele lassen sich in allen gängigen Programmiersprachen leicht lösen und gut debuggen. Sie lassen sich sogar in Kalkulations-Programmen (LibreOffice, OpenOffice, MS-Excel) leicht darstellen. |
RechenzeitFortgeschrittene EntwicklerInnen messen darüber hinaus die verwendete Rechenzeit.Dabei kann man das eigene Programm optimieren und die Wirkung kleiner Änderungen messen. Für die Programmierung schneller RealTime-Aufgaben ist es interessant zu messen, wie dramatisch sich die (oft sinnvolle) Verringerung der Genauigkeit auf die Rechenzeit auswirkt. |
GenauigkeitDie hier vorgestelten Reihen haben definitionsgemäß kein Ende, d.h. man kann unendlich viele Elemente berechnen.Bei sinnvollen Algorithmen sollte sich dabei das Ergebnis so rasch wie möglich dem theoretisch 'genauen' Wert nähern. Man kann diese Annäherung anschaulich mit der Anzahl übereinstimmender Dezimalstellen messen: Ein Ergebnis 3.18 stimmt z.B. auf 2 Stellen mit dem 'genauen' Wert von 3.14159265358979..... überein. Der zuletzt angeführte Wert ist jener, der mit üblichen Double-Precision Typen (15 Dezimal-Stellen) erreichbar ist. |
Für die praktische Anwendung muss man daher sinnvolle Grenzen setzen. Auf dieser Seite wird die Grenze mit einer Genauigkeit von 15 Dezimalstellen gesetzt: Das ist die maximale Genauigkeit aller gängigen Kalkulations-Programme und Programmiersprachen mit dem Standard Gleitkomma-Typ Double-Precision ( 8 Byte). Alle modernen Programmiersprachen bieten Module zum Rechnen mit beliebiger Genauigkeit (auf Kosten der Geschwindigkeit). Ein Beispiel mit ↓ Perl auf dieser Seite: Berechnung der ersten 500 Stellen von Pi. ♦ Details zu den Grenzen von Reihen, zu Gleitkomma-Zahlen und ihrer internen Darstellung nach IEEE-754 |
Monte-Carlo MethodeDie Berechnung der Kreiszahl Pi mit einem stochastischen Verfahren ist das klassische Beispiel der → Monte-Carlo-Methode zur 'Integration durch wiederholtes Probieren'. |
Der Vorteil der Methode liegt darin, dass sie von anderen Verfahren vollkommen unabhängig ist und keinerlei geometrische Kenntnisse oder Annahmen voraussetzt. Man muss den Algorithmus allerdings sehr oft wiederholen, um eine mit den Algorithmen dieser Seite vergleichbare Genauigkeit zu erhalten. |
Wikipedia:
Kreis (Formeln, Näherungen),
Kreiszahl,
Quadratur des Kreises (Näherungen),
|
Mathematische Basteleien (Formeln, anschauliche Beispiele) |
Pi in Programmiersprachen |
|||||||||||||
Kalkulations-Programme(LibreOffice-Calc, OpenOffice-Calc, MS-Excel, ...)Alle gängigen → Kalkulations-Programme bieten die Funktion PI() ♣ Tipp: Wenig geübte AnwenderInnen neigen dazu, die notwendigen () Klammern zu vergessen. |
Anwendung:
|
||||||||||||
Zeichen πDie Codierung des griechischen Zeichens Pi wird hier als Ergänzung vorgestellt: Mit dem Zeichen π kann man nicht rechnen.♣ Tipp: Verwenden sie keinesfalls das lateinische Zeichen p mit der Schrift-Familie 'Symbol', sondern nur das 'echte griechische' Unicode-Zeichen. Sogar M$-Programme bieten diese Möglichkeit, meist unter getarnten Namen wie 'Sonderzeichen' ... ♦ Details zum Unicode, zur Codierung und Programmierung von Zeichen |
• Unicode-Standard: U+03C0 (dezimal 960) • UTF-8: So wird das Zeichen in allen (international eindeutigen) XML-Daten dargestellt: 2 aufeinander folgende Bytes 0xCF,0x80 oder dezimal 207,128 Codierung im User-Interface: • Basic (LibreOffice-Basic, VBA): ChrW(960) • HTML: π oder π oder π • XML: π oder π • Javascript: \u03C0 oder String.fromCharCode(960) |
||||||||||||
Basic (LibreOffice-Basic, Visual Basic VBA)Basic ist die einzige ernstzunehmende Programmiersprache ohne jede Unterstützung von Pi.Man hilft sich entweder durch Definition einer Konstanten oder durch Berechnung von Pi: Konstante
Man kann Pi als globale Konstante definieren. Das ist in Basic die
sparsamste und schnellste Lösung.
|
Pi als Basic-Konstante:
Const const_pi = 3.14159265358979
Man kann zwar mehr Dezimalstellen angeben, diese werden jedoch von Basic ignoriert.Anwendung: bogenmass = grad * Const_pi / 180
Alternative: Berechnung mit der → ArcusTangens-Funktion:
Dim Pi As Double
Pi = 4 * Atn(1) |
||||||||||||
C/C++Diese Preprocessor-Makros sind meist definiert, werden jedoch als 'system-spezifisch' angegeben:
M_PI = 3.14159265358979323846
M_PI_2 = 1.57079632679489661923 M_PI_4 = 0.78539816339744830962 M_1_PI = 0.31830988618379067154 M_2_SQRTPI = 1.12837916709551257390 M_2_PI = 0.63661977236758134308 |
Alternativ kann man eine eigene Konstante definieren, z.B.: const double PI = 3.14159265358979;
|
||||||||||||
JavaDas Modul java.lang.Math ist in allen Java-Distributionen enthalten und definiert die Konstante PI |
Einbindung des Moduls in ein Java-Programm:
import java.lang.Math;
Anwendung:
umfang = 2 * radius * Math.PI;
|
||||||||||||
JavascriptBietet ohne weitere Maßnahmen die Konstante Math.PI |
Anwendung:
var umfang = 2 * radius * Math.PI;
|
||||||||||||
PerlWenn sie kein Perl-Modul laden, dann müssen sie die Kreiszahl selbst definieren, z.B. als (vom Compiler vor der Ausführung) 'berechnete Konstante' oder als einfache Variable:
use constant PI => 4 * atan2(1,1);
Die Definition der Konstanten PI ist flexibler, weil sie in jedem
Betriebssystem mit maximaler Genauigkeit arbeitet.my $pi = 3.141592653589793; ♦ Details zur Arcustangens-Funktion ● Im Modul Math::Trig sind einige Konstanten definiert: So wird das Modul in ein Perl Script-Programm eingebunden: use Math::Trig;
Auswahl einiger Konstanten dieses Perl-Moduls:
pi = π
Das Modul bietet alle wichtigen
→ trigonometrischen
Funktionen sowie Funktionen zur Umrechnung von Gradmaß und Bogenmaß.
pi2 = 2*π pip2 = π/2 pip4 = π/4 |
● Das Modul Math::Big bietet u.a. die Möglichkeit, Pi mit beliebiger Genauigkeit zu berechnen und in Rechnungen zu verwenden. Dieses Modul verwendet nicht die üblichen Zahlen-Typen sondern Ziffern-Strings. Das erlaubt beliebige Genauigkeit, ist jedoch vergleichsweise langsam: Die Berechnung von Pi auf 500 Stellen (rechts) benötigt auf gängigen Arbeits-PC fast 1 Sekunde. Berechnung von Pi mit beliebiger Genauigkeit, z.B. der ersten 500 Stellen:
use Math::Big qw/pi/;
Ausgabe:
my $pi=pi(500); print $pi;
3.141592653589793238462643383279502884197169399375
10582097494459230781640628620899862803482534211706 79821480865132823066470938446095505822317253594081 28481117450284102701938521105559644622948954930381 96442881097566593344612847564823378678316527120190 91456485669234603486104543266482133936072602491412 73724587006606315588174881520920962829254091715364 36789259036001133053054882046652138414695194151160 94330572703657595919530921861173819326117931051185 48074462379962749567351885752724891227938183011949 |
||||||||||||
PHPIm Mathematik-Modul sind einige Konstanten definiert, deren Namen alle mit M_ beginnen. Das Modul ist in der Standard-Ausrüstung aller PHP Distributionen enthalten.♦ Details und Live-Daten der → PHP-Konstanten |
Auswahl einiger PHP-Konstanten:
M_PI = π = 3.1415926535898
M_PI_2 = π/2 = 1.5707963267949 M_PI_4 = π/4 = 0.78539816339745 M_1_PI = 1/π = 0.31830988618379 M_2_PI = 2/π = 0.63661977236758 M_SQRTPI = sqrt(π) = 1.7724538509055 M_2_SQRTPI = 2/sqrt(π) = 1.1283791670955 M_LNPI = ln(π) = 1.1447298858494 |
||||||||||||
PythonDas Modul math definiert die Konstante math.pi |
Dieses Modul ist in der Standard-Ausrüstung aller Python Distributionen enthalten. |
||||||||||||
RubyBietet die Konstante Math::PI im Modul Math, das in jeder Ruby Distribution enthalten ist. |
Einbindung des Moduls Math: include Math
|
||||||||||||
|
Arcus-Tangens
Eine klassische Methode berechnet Pi mit Hilfe der
→
Arcustangens-Funktion. Dafür müssen 2 Bedingungen erfüllt sein:• Diese Funktion ist (in der jeweiligen Programmiersprache) verfügbar • Es ist genügend Zeit vorhanden: Gleitkomma-Funktionen rechnen vergleichsweise langsam und außerdem immer bis zur maximalen Genauigkeit (15 Dezimalstellen). |
Beispiel: Berechnung von Pi in Basic:
Dim my_pi As Double
my_pi = 4 * Atn(1) ♣ Die Berechnung von Atn(1) ist nach den üblichen → Algorithmen besonders langsam. Die meisten Programmen fangen diesen Fall ab und geben direkt das Ergebnis =π/4 aus. Deshalb ist die Berechnung in diesem Sonderfall sogar besonders schnell. |
||||||||||||
|
Optionale Argumente
Für alle hier vorgestellten Algorithmen wird auch ein Beispiel in
→ Basic gezeigt,
das sowohl in LibreOffice-Basic als auch in MS-Visual Basic (VBA) funktioniert.• Eine Basic-Funktion kann optionale Argumente enthalten: Man kann das betreffende Argument in diesem Fall wahlweise angeben oder nicht. Wenn das Argument fehlt, dann setzt das Programm mit Hilfe der Funktion IsMissing() einen Standard-Wert ein. |
Verqwendung eines optionalen Arguments :
Function demo(Optional arg As Variant)
Die vorgestellte Programmierung funktioniert nur dann, wenn man sich genau an diese Regeln hält:
If IsMissing(arg) Then arg = 12345
End Function
demo = arg • Optionale Argumente müssen mit dem Typ Variant angegeben werden. • Die Zuweisung fehlender Werte muss mit Funktion IsMissing() erfolgen. Eine Zuweisung bei der Deklaration der Argumente (in der 1.Zeile einer Funktion) ist nicht zulässig. |
||||||||||||
Berechnung von Pi nach François Viète, 1593 |
||||||||||||||||||||||
Dieser elegante Algorithmus ergibt schon nach wenigen Schritten ausgezeichnete
Ergebnisse:
Quelle: Wikipedia
Man braucht etwas mathematische Phantasie und IT-Erfahrung, um aus einer derartigen
Darstellung ein Programm abzuleiten.
|
Der Algorithmus ist einfach zu berechnen, konvergiert relativ rasch, und hat nur
einen Nachteil: Braucht die Wurzel-Funktion Sqr() Wenn man auch diese mit Hilfe einer ↓ Iteration (nach Heron, in diesem Kapitel) berechnet, dann werden nur die 4 Grundrechnungs-Arten verwendet: Addition, Subtraktion, Multiplikation, Division. |
|||||||||||||||||||||
ProgrammierungAnzahl der Iterationen
Alle Funktionen dieser Seite akzeptieren als optionales Argument
nmax die Anzahl der zu berechnenden Reihen-Elemente. Das ist für
Experimente sinnvoll. Gleich zu Beginn wird der Wert dieser Variablen begrenzt
(hier auf 1000 Schritte), damit man eine Endlos-Schleife sicher verhindert.Anfangs-Werte
Vor Beginn der Berechnungs-Schleife werden Anfangswerte gesetzt: Summen auf =0,
Produkte auf =1 und eine eigene Variable doloop für
den Abbruch der Rechnungn ... Zähler für die Elemente der Reihe Berechnung
Die Rechnung erfolgt in einer while-Schleife. Bei jedem
Durchlauf wird 1 Element der Reihe berechnet.zaehler ... Berechnung des Zählers. Beachten sie, dass der Zähler in jedem weiteren Schritt lediglich ergänzt, jedoch nicht komplett neu berechnet wird. In der abgeschalteten Zeile wird angedeutet, wie man die Wurzel-Funktion durch eine eigene Reihen-Entwicklung ersetzt. produkt ... In jedem Schleifen-Durchgang wird das Produkt = Ergebnis der Rechnung mit dem aktuellen Element multipliziert. Abbruch
vprodukt ... Vor jeder Neu-Berechnung des Produkts wird
dessen aktueller Wert in dieser Variablen gespeichert. Nach Neu-Berechnung wird
verglichen: Wenn sich das Ergebnis nicht mehr geändert hat, oder wenn die
maximale Anzahl von Elementen berechnet wurde, dann wird
doloop=False gesetzt und die Schleife abgebrochen.Rückgabe
Zuletzt wird das berechnete Ergebnis zurückgegeben.
|
Reihen-Entwicklung nach Viète als Basic-(VBA)-Funktion:
Function pi_viete( _
Optional nmax As Variant) _
Dim doloop As BooleanAs Double Dim n As Integer Dim zaehler, produkt, vprodukt As Double
If (IsMissing(nmax)) Then nmax=1000
End Function
If (nmax < 0) Then nmax = 1000 ' Anfangs-Werte
doloop = Truezaehler = 0 produkt = 1 n = 0 ' Iterations-Schleife
While doloop
vprodukt = produkt
Wendzaehler = Sqr(2 + zaehler) ' zaehler = my_sqrt(2 + zaehler)
produkt = produkt * zaehler / 2n = n + 1 ' Iterations-Zaehler If (produkt=vprodukt Or n>=nmax) Then doloop = False
End If
' Ergebnis
pi_viete = 2 / produkt
|
|||||||||||||||||||||
AnwendungIn jedem Kalkulations-Programm (LibreOffice-Calc, OpenOffiice-Calc, MS-Excel, ...) kann man die Berechnung verfolgen Die VBA-Funktion wird als 'Benutzer-definierte Funktion' eingesetzt.• Berechnung mit maximaler Genauigkeit: In Zelle B3 wird Pi nach Viète bis zum Abbruch berechnet (normalerweise 26 Elemente) • Analyse der Methode: In den Zellen B4..B6 wird pi_viete() lediglich aus den ersten 1..3 Elementen berechnet. Verlängern sie die Tabelle nach unten und beobachten sie den Verlauf der Iteration: Das Ergebnis nähert sich in immer kleineren Schritten dem theoretischen Wert. |
Anwendung
♣ Auf ähnliche Weise kann man auch alle anderen hier vorgestellten Algorithmen mit VBA-Funktionen testen. |
|||||||||||||||||||||
Wurzel mit Heron-AlgorithmusDer einzige wesentliche Nachteil des Viète-Algorithmus ist die Verwendung der Wurzel-Funktion. Mit der Funktion my_sqrt() (rechts) lässt sich diese ersetzen: Sie verwendet eine andere Reihe (→ Heron) zur Berechnung der Wurzel. Damit ist der gesamte Algorithmus ausschließlich mit den 4 Grundrechnungs-Arten durchgeführt.Einzige Änderung der Funktion gegenüber dem Standard → Heron-Algorithmus ist der Start-Wert x=3 mit dem die Funktion für alle Beispiele dieser Seite am schnellsten berechnet wird. Die Quadratwurzel wird hier mit maximaler Genauigkeit berechnet. Mit reduzierter Genauigkeit (je nach Anforderung) kann man den Algorithmus weiter beschleunigen. |
Quadratwurzel nach → Heron
als Basic-(VBA)-Funktion:
Function my_sqrt( _
a As Double, _
Dim doloop As BooleanOptional nmax As Variant) _ As Double Dim n As Integer Dim x, xv As Double
If (IsMissing(nmax)) Then nmax=1000
End Function
If (nmax < 0) Then nmax = 1000 ' Anfangwerte
doloop = Truex = 3 ' Spezialfall n = 0 ' Schleife
While doloop
xv = x
Wendx = (x + a / x) / 2 n = n + 1 If (x=xv Or n>=nmax) Then doloop = False my_sqrt = x |
|||||||||||||||||||||
JavascriptDie Javascript Funktion pi_viete() (rechts) berechnet Pi nach dem Algorithmus von Viète und verwendet zur Berechnung der Quadratwurzel den Algorithmus von → Heron.Die Funktion ist im Quelltext dieser Webseite enthalten und berechnet Pi Live, wenn sie den Button klicken:
Live-Ergebnis:
Pi = ?
Genauigkeit ≈ ? Dezimalstellen Anzahl der Iterationen = ? Rechenzeit = ? µs Hinweise:
•
Das Ergebnis wird Live von ihrem PC bis zur maximal erreichbaren Genauigkeit berechnet.• Das Ergebnis von Pi und die Anzahl der ausgeführten Iterationen (Variable n des Beispiels) sollte normalerweise bei jeder Wiederholung gleich bleiben. • Zur Messung der Zeit wird die Funktion 1000mal Live ausgeführt und der Mittelwert der einzelnen Ausführungen in µs (Mikrosekunden = 1/1000000s) angegeben. Diese Zeit hängt von der Rechenleistung ihres PC sowie vom Javascript-Engine ihres Browsers ab. Außerdem schwankt die Zeit je nach der momentanen Auslastung ihres PC. |
Reihen-Entwicklung nach Viète als
Javascript-(JS)-Funktion. ♣ Die JS-Funktionen dieser Seite sind kompakter programmiert und nicht mehr kommentiert).
function pi_viete() {
var nmax = 100;
}var doloop = true; var zaehler = 0; var produkt = 1; var vprodukt = 1; var n=0; while(doloop) {
vprodukt = produkt;
}zaehler = my_sqrt(zaehler+2); produkt *= zaehler / 2; n++; if(produkt==vprodukt || n>=nmax) {doloop=false;} return (2/produkt); function my_sqrt(a) {
var doloop = true;
}
var nmax = 100; var x = 2; var vx = 0; var m = 0; while(doloop) {
vx = x;
}
return x;
x = (x+a/x) / 2; n++; if(x==vx || n>=nmax) {doloop=false;} |
|||||||||||||||||||||
Berechnung von Pi nach John Wallis, 1655 |
|
Quelle: Wikipedia
Dieser Algorithmus sieht einfach und übersichtlich aus. Man muss nur eine Methode finden, um die Werte von Zähler und Nennen mit möglichst wenig Aufwand zu programmieren. Das wird hier mit der Schalter-Variablen zn erreicht: Am Beginn jedes Schleifen-Durchgangs wird je nach zn entweder der Zähler oder der Nenner um +2 erhöht. Am Ende jeder Schleife wird zn umgeschaltet. Die übrige Programmiersung folgt (absichtlich) genau dem Muster des ersten Beispiels (↑ Pi nach Viète) Die Methode braucht keine anderen Funktionen, kommt jedoch sehr langsam voran. Die Ergebnisse von 2 aufeinander folgenden Iterationen liegen stets symmetrisch zum theoretischen Ergebnis. Man kann das ausnutzen: Der Mittelwert der beiden letzten Iterationen ist immer genauer als die letzte Iteration selbst. Mit einem Kalkulations-Programm kann man höchstens einige 1000 Elemente berechnen. Mit Basic geht das schon schneller: Je nach Rechenleistung des PC kann man in ein paar Sekunden bis zu 1 Mio Elemente berechnen und erreicht in diesem Fall eine Genauigkeit von ca. 12 Stellen. Die maximale Kalkulations-Genauigkeit von 15 Stellen wird erst mit ca. 35 Mio Elementen erreicht. |
Reihen-Entwicklung nach Wallis als
Basic-(VBA)-Funktion:
Function pi_wallis( _
Optional nmax As Variant) _
Dim doloop, zn As BooleanAs Double Dim n As Long Dim zaehler, nenner, element, produkt, vprodukt As Double
If (IsMissing(nmax)) Then nmax=1000 End Function
If (nmax < 0) Then nmax = 1000 ' Anfangs-Werte
doloop = Truezn = True zaehler = 0 nenner = 1 produkt = 1 n = 0 ' Iterations-Schleife
While doloop
vprodukt = produkt
WendIf zn Then zaehler = zaehler + 2
Else
nenner = nenner + 2
End Ifelement = zaehler / nenner produkt = produkt * element n = n + 1 If (produkt=vprodukt Or n>=nmax) Then doloop = False
End Ifzn = Not zn pi_wallis = 2 * produkt |
JavascriptDie Javascript Funktion pi_wallis() (rechts) berechnet Pi nach dem Algorithmus von Wallis. Da sie nur sehr langsam konvergiert, ist die Anzahl der Iterationen und damit die Genauigkeit begrenzt. Deshalb wird zum Vergleich der theoretische Wert von Pi angegeben.Die Funktion ist im Quelltext dieser Webseite enthalten und berechnet Pi Live, wenn sie einen der Buttons klicken:
Live-Ergebnis:
Pi (berechnet) = ?
Beobachten sie Live, wie sich die Rechenzeit und die erreichte Genauigkeit mit der
Anzahl der Iterationen ändert.
Pi (theoret.) = ? Genauigkeit ≈ ? Dezimalstellen Anzahl der Iterationen = ? Rechenzeit = ? µs |
Reihen-Entwicklung nach Wallis als Javascript-Funktion:
function pi_wallis() {
var nmax = 1000000;
}
var doloop = true; var zn = true; var zaehler = 0; var nenner = 1; var produkt = 1; var vprodukt = 0; var n = 0; while(doloop) {
vprodukt = produkt;
}if(zn) {zaehler+=2;} else{nenner+=2;} produkt *= zaehler / nenner; n++; if(produkt==vprodukt || n>=nmax) {doloop=false;} zn = !zn; return (2*produkt); |
|
Hinweise:
•
Das Ergebnis wird Live von ihrem PC berechnet.• Die Anzahl der Iterationen wird auf 10000 (10k) bis 10Mio (10M) begrenzt, damit die Rechenzeit überschaubar bleibt. • Das Ergebnis hängt von der Anzahl der Iterationen ab. Für jede Verzehnfachung der Iterationen nimmt die Genauigkeit um ca. 1 Dezimalstelle zu. |
• Die Hochrechnung ergibt einen Bedarf von ca. 3E+14 Iterationen für die maximale Genauigkeit von 15 Dezimalstellen. Dazu müssten nach dem Button '10M' noch weitere 8 Buttons mit jeweils der 10fachen Anzahl von Iterationen folgen. |
Berechnung von Pi nach Gottfried Wilhelm Leibnitz, 1682 |
|
Quelle: Wikipedia
Der Algorithmus ist besonders einfach und schnell zu berechnen, braucht keine anderen Funktionen, konvergiert jedoch sehr langsam. Ein großer Forschritt dieser Methode ist die Verwendung einer Summe an Stelle eines Produkts: Summen lassen sich auf Prozessor-Ebene wesentlich rascher berechnen. Leider kommt die Methode nur sehr langsam voran. Dank der schnelleren Berechnung kann man mit Basic problemlos 10..100 Mio Elemente (10E7..10E8) berchnen. Bis zur maximalen Kalkulations-Genauigkeit von 15 Dezimalstellen müsste man jedoch ca. 1.5E15 Elemente berechnen. |
Reihen-Entwicklung nach Leibnitz als
Basic-(VBA)-Funktion:
Function pi_leibnitz( _
Optional nmax As Variant) _
Dim doloop As BooleanAs Double Dim zaehler As Integer Dim n, nenner As Long Dim element, sum, vsum As Double
If (IsMissing(nmax)) Then nmex=1000 End Function
If (nmax < 0) Then nmax = 1000 ' Anfangs-Werte
doloop = Truezaehler = 1 sum = 0 n = 0 ' Iterations-Schleife
While doloop
vsum = sum
Wendnenner = 2 * n + 1 element = zaehler / nenner sum = sum + element n = n + 1 If (sum=vsum Or n>=nmax) Then doloop = False
End If zaehler = zaehler * -1 pi_leibnitz = 4 * sum |
JavascriptDie Javascript Funktion pi_leibnitz() (rechts) berechnet Pi nach dem Algorithmus von Leibnitz. Da sie nur sehr langsam konvergiert, ist die Anzahl der Iterationen und damit die Genauigkeit begrenzt. Deshalb wird zum Vergleich der theoretische Wert von Pi angegeben.Die Funktion ist im Quelltext dieser Webseite enthalten und berechnet Pi Live, wenn sie einen der Buttons klicken:
Live-Ergebnis:
Pi (berechnet) = ?
Beobachten sie Live, wie sich die Rechenzeit und die erreichte Genauigkeit mit der
Anzahl der Iterationen ändert.
Pi (theoret.) = ? Genauigkeit ≈ ? Dezimalstellen Anzahl der Iterationen = ? Rechenzeit = ? µs |
Reihen-Entwicklung nach Leibnitz als Javascript-Funktion:
function pi_leibnitz() {
var nmax = 1000000;
}
var doloop = true; var zaehler = 1; var sum=0; var vsum=0; var n = 0; while(doloop) {
vsum = sum;
}sum += zaehler/(2*n+1); n++; if(sum==vsum || n>=nmax) {doloop=false;} zaehler *= -1; return (4*sum); |
Berechnung von Pi nach John Malcolm, 1706 |
|
Quelle: Wikipedia
Diese Methode benötigt zwar die → Arcustangens-Funktion, diese lässt sich jedoch bequem und sogar außerordentlich rasch mit einer Reihe berechnen (nächster Absatz). Die Methode rechnet sehr schnell und erreicht schon mit 9-10 Elementen die maximale Kalkulations-Genauigkeit von 15 Stellen. |
Reihen-Entwicklung nach Malcolm als
Basic-(VBA)-Funktion:
Function pi_malcolm( _
Optional nmax As Variant) _
Dim a, b As Double
As Double
If (IsMissing(nmax)) Then nmax=1000
End Function
If (nmax < 0) Then nmax = 1000 a = my_arctan(1 / 5, iter) b = my_arctan(1 / 239, iter) pi_malcolm = 4 * (4 * a - b) |
Berechnung der Arcustangens-Funktionmit einer Taylor-Reihe:
Quelle: Wikipedia
Die Berechnung folgt dem gleichen Schema wie alle anderen hier vorgestellten Algorithmen: Einzige Besonderheit: Das Vorzeichen vorz wird in jedem Schleifen-Durchgang umgekehrt. Interne Anwendung: atn_x = my_arctan(x,nmax)
Die Funktion erwartet 2 Argumente:x ... Winkel im Bogenmaß 0..2*π nmax ... Anzahl der Iterationen - In diesem Fall nicht optional, da die Funktion nur für interne Anwendung (durch andere VBA-Programme) ausgelegt ist. |
Private Function my_arctan( _
x As Double,
Dim doloop As BooleanByVal nmax As Integer) _ As Double Dim n, i, vorz As Integer Dim element, sum, vsum As Double
doloop = True
vorz = 1 sum = 0 n = 0 While doloop
vsum = sum
Wendi = 2 * n + 1 element = vorz * my_pow(x, i) / i sum = sum + element n = n + 1 If (sum=vsum Or n>=nmax) Then dloop = False
End Ifvorz = vorz * -1 my_arctan = sum End Function |
Berechnung der Potenz-FunktionDamit ist auch die letzte Funktion dieses Beispiels auf die 4 Grundrechnungs-Arten zurückgeführt.Interne Anwendung: x_hoch_y = my_pow(x,y)
Die Funktion erwartet 2 Argumente:x ... Basis y ... Exponent (ganze Zahl 0...32767) Die Funktion ist nur für diesem speziellen Fall geeignet. Für allgemeine Anwendung müsste man sie auch für negative und Gleitkomma-Exponenten auslegen. |
Private Function my_pow( _
ByVal number As Double, _
Dim i As IntegerByVal exponent As Integer) _ As Double Dim p As Double
p = 1
End Function
For i = 1 To exponent p = p * number
Nextmy_pow = p |
JavascriptDie Javascript Funktion pi_malcolm() (rechts) berechnet Pi nach dem Algorithmus von Malcolm.Die Funktion ist im Quelltext dieser Webseite enthalten und berechnet Pi Live, wenn sie den Button klicken:
Live-Ergebnis:
Pi = ?
Genauigkeit ≈ ? Dezimalstellen Anzahl der Iterationen = ? Rechenzeit = ? µs Hinweis:
•
Das Ergebnis wird Live von ihrem PC bis zur maximal erreichbaren Genauigkeit von ca.
15 Dezimalstellen berechnet.• Für die beiden Variablen a und b werden unterschiedlich viele Iterationen gebraucht, die getrennt angeführt werden. |
Reihen-Entwicklung nach Malcolm als
Javascript-Funktion:
function pi_malcolm() {
var a = my_arctan(1/5);
}var b = my_arctan(1/239); return 4*(4*a-b); function my_arctan(x) {
var doloop = true;
}var vorz = 1; var sum=0; var vsum=0; var i = 0; var n = 0; while(doloop) {
vsum = sum;
}i = 2 * n + 1; sum += vorz*my_pow(x, i)/i; n++; if(sum==vsum || n>1000) {doloop=false;} vorz *= -1; return sum; function my_pow(b,e) {
var p=1;
}
for(var i=1;i<=e;i++) {p*=b;} return p; |
Berechnung von Pi nach Leonhard Euler, 1748 |
|
Von Leonhard Euler stammen mehrere Methoden zur Berechnung von Pi:
Quelle: Wikipedia
Dieser Algorithmus ist einfach zu berechnen, konvergiert jedoch sehr langsam. Die Quadratwurzel wird mit einer eigenen Funktion (hier my_sqr() aus dem Kapitel ↑ Pi @ Viète) berechnet. |
Auch dieser Algorithmus stammt von Leonhard Euler:
Quelle: Wikipedia
Einfach zu berechnen, konvergiert jedoch wesentlich schneller. |
|
Reihen-Entwicklung (1) nach Euler als
Basic-(VBA)-Funktion:
Function pi_euler_1( _
Optional nmax As Variant) _
Dim doloop As BooleanAs Double Dim n As Long Dim i, element, sum, vsum As Double
If (IsMissing(nmax)) Then nmax=1000
End Function
If (nmax < 0) Then nmax = 1000 ' Anfangs-Werte
doloop = Truesum = 0 n = 0 ' Iterations-Schleife
While doloop
vsum = sum
Wendi = n + 1 element = 1 / (i * i) sum = sum + element n = n + 1 If (sum=vsum Or n>=nmax) Then doloop = False
End If
pi_euler_1 = my_sqr(6 * sum) |
Reihen-Entwicklung (2) nach Euler als
Basic-(VBA)-Funktion:
Function pi_euler_2( _
Optional nmax As Variant) _
Dim doloop As BooleanAs Double Dim vorz As Integer Dim n As Long Dim i, element, sum, vsum As Double
If (IsMissing(nmax)) Then nmax=1000 End Function
If (nmax < 0) Then nmax = 1000 ' Anfangs-Werte
doloop = Truesum = 0 vorz = 1 n = 0 ' Iterations-Schleife
While doloop
vsum = sum
Wendi = 2 * (n + 1) element = vorz / (i * (i + 1) * (i + 2)) sum = sum + element n = n + 1 If (sum=vsum Or n>=nmax) Then doloop = False
End Ifvorz = vorz * -1 pi_euler_2 = sum * 4 + 3 |
|
Reihen-Entwicklung nach Euler (1) als
Javascript-Funktion:
function pi_euler_1() {
var nmax = 1000;
}
var doloop = true; var sum=0; var vsum=0; var n = 0; var i = 0; while(doloop) {
vsum = sum;
}i = n+1; sum += 1/(i*i); n++; if(sum==vsum || n>=nmax) {doloop=false;} return my_sqrt(6*sum); |
Reihen-Entwicklung nach Euler (2) als
Javascript-Funktion:
function pi_euler_2(iter) {
var nmax = 1000;
}
var doloop=true; var vorz=1; var sum=0; var vsum=0; var n=0; var i=0; while(doloop) {
vsum = sum;
}i = 2 * (n+1); sum += vorz / (i*(i+1)*(i+2)); n++; if(sum==vsum || n>=nmax) {doloop=false;} vorz *= -1; return (sum*4+3); |
JavascriptDie Javascript Funktion pi_euler_1() (oben) berechnet Pi nach dem Algorithmus von Euler (1).Die Funktion ist im Quelltext dieser Webseite enthalten und berechnet Pi Live, wenn sie einen dieser Buttons klicken:
Live-Ergebnis:
Pi = ?
Genauigkeit ≈ ? Dezimalstellen Anzahl der Iterationen = ? Rechenzeit = ? µs |
Die Javascript Funktion pi_euler_2() (oben) berechnet Pi nach dem Algorithmus von Euler (2). Die Funktion ist im Quelltext dieser Webseite enthalten und berechnet Pi Live, wenn sie einen dieser Buttons klicken:
Live-Ergebnis:
Pi = ?
Genauigkeit ≈ ? Dezimalstellen Anzahl der Iterationen = ? Rechenzeit = ? µs |
Berechnung von Pi nach Bailey, Borwein, Plouffe, 1996 |
|
Quelle: Wikipedia
|
|
Diese Methode erwies sich als außerordentlich effizient. Sie rechnet sehr
rasch und erreicht bereits nach 11 Elementen die maximale Gleitkomma-Genauigkeit
von 15 Stellen.Programmierung:Der Term 1/(16^n) vor der Klammer wird in der Variablen t0 berechnet, die 4 Terme innerhalb der Klammer in den Variablen t1 bis t4Innerhalb jedes Schleifen-Durchgangs wird je 1 Element berechnet, d.h. aus den Variablen t0...t4 zusammengesetzt und zum Ergebnis sum addiert. Die für t0 benötigte Potenz-Funktion wird mit der selbst programmierten Funktion my_pow() (Kapitel ↑ Pi nach Malcolm) ausgeführt. Damit ist der gesamte Algorithmus auf die 4 Grundrechnungs-Arten zurückgeführt. |
Reihen-Entwicklung (2) nach BBP als
Basic-(VBA)-Funktion:
Function pi_bbp( _
Optional nmax As Variant) _
Dim doloop As BooleanAs Double Dim n As Integer Dim t0, t1, t2, t3, t4 As Double Dim element, sum, vsum As Double
If (IMissing(nmax)) Then nmax=1000
End Function
If (nmax < 0) Then nmax = 1000 ' Anfangs-Werte
doloop = Truesum = 0 n = 0 ' Iterations-Schleife
While doloop
vsum = sum
Wendt0 = my_pow(1 / 16, n) t1 = 4 / (8 * n + 1) t2 = 2 / (8 * n + 4) t3 = 1 / (8 * n + 5) t4 = 1 / (8 * n + 6) element = t0 * (t1 - t2 - t3 - t4) sum = sum + element n = n + 1 If (sum=vsum Or n>=nmax) Then doloop = False
End If
pi_bbp = sum |
JavascriptDie Javascript Funktion pi_bbp() (rechts) berechnet Pi nach dem BBP-Algorithmus.Die Funktion ist im Quelltext dieser Webseite enthalten und berechnet Pi Live, wenn sie den Button klicken:
Live-Ergebnis:
Pi = ?
Genauigkeit ≈ ? Dezimalstellen Anzahl der Iterationen = ? Rechenzeit = ? µs |
Reihen-Entwicklung nach BBP als
Javascript-Funktion:
function pi_bbp() {
var nmax = 100;
}
var doloop = true; var sum=0; var vsum=0; var n = 0; var t0=0; var t1=0; var t2=0; var t3=0; var t4=0; var t16 = 1/16; while(doloop) {
vsum = sum;
}t0 = my_pow(t16,n); t1 = 4/(8*n+1); t2 = 2/(8*n+4); t3 = 1/(8*n+5); t4 = 1/(8*n+6); sum+=t0*(t1-t2-t3-t4); n++; if(sum==vsum || n>=nmax) {doloop=false;} return sum; |
Quelle: Wikipedia
Weitere BBP-ReihenMittlerweile fand man einige weitere ähnliche BBP-Reihen (rechts).Die Programmierung kann mit geringen Änderungen nach dem gezeigten Muster erfolgen. |
|