Die Kreiszahl PI

Berechnung durch Reihen-Entwicklung

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)
Hinweis: Die hier angegebenen Rechenzeiten sind lediglich Richtwerte zum Vergleich der Algorithmen.

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.

Rechenzeit

Fortgeschrittene 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.

Genauigkeit

Die 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 Methode

Die 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:
     AB
1Radius123
2Umfang=2*B1*PI()
3Fläche=B1*B1*PI()

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: &#x3C0 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;

Java

Das 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;

Javascript

Bietet ohne weitere Maßnahmen die Konstante Math.PI
Anwendung:
var umfang = 2 * radius * Math.PI;

Perl

Wenn 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);
my $pi = 3.141592653589793;
Die Definition der Konstanten PI ist flexibler, weil sie in jedem Betriebssystem mit maximaler Genauigkeit arbeitet.
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 = π
pi2 = 2*π
pip2 = π/2
pip4 = π/4
Das Modul bietet alle wichtigen → trigonometrischen Funktionen sowie Funktionen zur Umrechnung von Gradmaß und Bogenmaß.

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/;
my $pi=pi(500);
print $pi;
Ausgabe:
3.141592653589793238462643383279502884197169399375
10582097494459230781640628620899862803482534211706
79821480865132823066470938446095505822317253594081
28481117450284102701938521105559644622948954930381
96442881097566593344612847564823378678316527120190
91456485669234603486104543266482133936072602491412
73724587006606315588174881520920962829254091715364
36789259036001133053054882046652138414695194151160
94330572703657595919530921861173819326117931051185
48074462379962749567351885752724891227938183011949

PHP

Im 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

Python

Das Modul math definiert die Konstante math.pi

Dieses Modul ist in der Standard-Ausrüstung aller Python Distributionen enthalten.

Ruby

Bietet 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)
If IsMissing(arg) Then arg = 12345
demo = arg
End Function
Die vorgestellte Programmierung funktioniert nur dann, wenn man sich genau an diese Regeln hält:
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.

Programmierung


Anzahl 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 Rechnung
n ... 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) _
As Double
Dim doloop As Boolean
Dim n As Integer
Dim zaehler, produkt, vprodukt As Double
If (IsMissing(nmax)) Then nmax=1000
If (nmax < 0) Then nmax = 1000
' Anfangs-Werte
doloop = True
zaehler = 0
produkt = 1
n = 0

' Iterations-Schleife
While doloop
vprodukt = produkt
zaehler = Sqr(2 + zaehler)
' zaehler = my_sqrt(2 + zaehler)
produkt = produkt * zaehler / 2
n = n + 1   ' Iterations-Zaehler
If (produkt=vprodukt Or n>=nmax) Then
doloop = False
End If
Wend

' Ergebnis
pi_viete = 2 / produkt
End Function

Anwendung

In 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
     AB
1Pi-Standard:=PI()
2Pi nach Viete:=pi_viete()
3SchritteErgebnis
41=pi_viete(B4)
5=A4+1=pi_viete(B5)
6=A5+1=pi_viete(B6)

Auf ähnliche Weise kann man auch alle anderen hier vorgestellten Algorithmen mit VBA-Funktionen testen.

Wurzel mit Heron-Algorithmus

Der 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, _
Optional nmax As Variant) _
As Double
Dim doloop As Boolean
Dim n As Integer
Dim x, xv As Double
If (IsMissing(nmax)) Then nmax=1000
If (nmax < 0) Then nmax = 1000
' Anfangwerte
doloop = True
x = 3   ' Spezialfall
n = 0
' Schleife
While doloop
xv = x
x = (x + a / x) / 2
n = n + 1
If (x=xv Or n>=nmax) Then doloop = False
Wend
my_sqrt = x
End Function

Javascript

Die 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;
x = (x+a/x) / 2;
n++;
if(x==vx || n>=nmax) {doloop=false;}
} return x;
}

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) _
As Double
Dim doloop, zn As Boolean
Dim n As Long
Dim zaehler, nenner, element, produkt, vprodukt As Double
If (IsMissing(nmax)) Then nmax=1000
If (nmax < 0) Then nmax = 1000
' Anfangs-Werte
doloop = True
zn = True
zaehler = 0
nenner = 1
produkt = 1
n = 0
' Iterations-Schleife
While doloop
vprodukt = produkt
If zn Then
zaehler = zaehler + 2
Else
nenner = nenner + 2
End If
element = zaehler / nenner
produkt = produkt * element
n = n + 1
If (produkt=vprodukt Or n>=nmax) Then
doloop = False
End If
zn = Not zn
Wend
pi_wallis = 2 * produkt
End Function

Javascript

Die 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) = ?
Pi (theoret.)  = ?
Genauigkeit ≈ ? Dezimalstellen
Anzahl der Iterationen = ?
Rechenzeit = ? µs
Beobachten sie Live, wie sich die Rechenzeit und die erreichte Genauigkeit mit der Anzahl der Iterationen ändert.

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) _
As Double
Dim doloop As Boolean
Dim zaehler As Integer
Dim n, nenner As Long
Dim element, sum, vsum As Double
If (IsMissing(nmax)) Then nmex=1000
If (nmax < 0) Then nmax = 1000
' Anfangs-Werte
doloop = True
zaehler = 1
sum = 0
n = 0
' Iterations-Schleife
While doloop
vsum = sum
nenner = 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
Wend
pi_leibnitz = 4 * sum
End Function

Javascript

Die 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) = ?
Pi (theoret.)  = ?
Genauigkeit ≈ ? Dezimalstellen
Anzahl der Iterationen = ?
Rechenzeit = ? µs
Beobachten sie Live, wie sich die Rechenzeit und die erreichte Genauigkeit mit der Anzahl der Iterationen ändert.

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) _
As Double
Dim a, b As Double
If (IsMissing(nmax)) Then nmax=1000
If (nmax < 0) Then nmax = 1000 a = my_arctan(1 / 5, iter)
b = my_arctan(1 / 239, iter)
pi_malcolm = 4 * (4 * a - b)
End Function

Berechnung der Arcustangens-Funktion

mit 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,
ByVal nmax As Integer) _
As Double
Dim doloop As Boolean
Dim n, i, vorz As Integer
Dim element, sum, vsum As Double
doloop = True
vorz = 1
sum = 0
n = 0
While doloop
vsum = sum
i = 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 If
vorz = vorz * -1
Wend
my_arctan = sum
End Function

Berechnung der Potenz-Funktion

Damit 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, _
ByVal exponent As Integer) _
As Double
Dim i As Integer
Dim p As Double
p = 1
For i = 1 To exponent
p = p * number
Next
my_pow = p
End Function

Javascript

Die 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) _
As Double
Dim doloop As Boolean
Dim n As Long
Dim i, element, sum, vsum As Double
If (IsMissing(nmax)) Then nmax=1000
If (nmax < 0) Then nmax = 1000
' Anfangs-Werte
doloop = True
sum = 0
n = 0
' Iterations-Schleife
While doloop
vsum = sum
i = n + 1
element = 1 / (i * i)
sum = sum + element
n = n + 1
If (sum=vsum Or n>=nmax) Then
doloop = False
End If
Wend
pi_euler_1 = my_sqr(6 * sum)
End Function
Reihen-Entwicklung (2) nach Euler als Basic-(VBA)-Funktion:
Function pi_euler_2( _
Optional nmax As Variant) _
As Double
Dim doloop As Boolean
Dim vorz As Integer
Dim n As Long
Dim i, element, sum, vsum As Double
If (IsMissing(nmax)) Then nmax=1000
If (nmax < 0) Then nmax = 1000
' Anfangs-Werte
doloop = True
sum = 0
vorz = 1
n = 0
' Iterations-Schleife
While doloop
vsum = sum
i = 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 If
vorz = vorz * -1
Wend
pi_euler_2 = sum * 4 + 3
End Function
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);
}

Javascript

Die 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 t4
Innerhalb 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) _
As Double
Dim doloop As Boolean
Dim n As Integer
Dim t0, t1, t2, t3, t4 As Double
Dim element, sum, vsum As Double
If (IMissing(nmax)) Then nmax=1000
If (nmax < 0) Then nmax = 1000
' Anfangs-Werte
doloop = True
sum = 0
n = 0
' Iterations-Schleife
While doloop
vsum = sum
t0 = 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
Wend
pi_bbp = sum
End Function

Javascript

Die 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-Reihen

Mittlerweile fand man einige weitere ähnliche BBP-Reihen (rechts).

Die Programmierung kann mit geringen Änderungen nach dem gezeigten Muster erfolgen.