Bernoulli-Zahlen

Berechnung der Bernoulli-Zahlenfolge B[k]

In einigen Bereichen der Mathematik - insbesondere in Reihen-Entwicklungen - werden die Bernoulli-Zahlen verwendet, eine Folge von Konstanten. Auf dieser Seite wird die Berechnung der Bernoulli-Zahlen vorgestellt: Aus tabellierten Bruchzahlen oder mit Reihen-Entwicklung.
Algorithmen Ausgewählte IT-Rezepte, Reihen-Entwicklung (Iteration)
Bernoulli-Zahlen Definition, tabellierte Werte, Algorithmen
Werte-Liste Tabelle der ersten 20 Bernoulli-Zahlen
Algorithmen Vorstellung der hier verwendeten Algorithmen zur Berechnung der Bernoulli-Zahlen
Kalkulation Berechnung der Bernoulli-Zahlen mit einem Kalkulations-Programm (LibreOffice, MS-Excel, ...)
Basic Benutzer-definierte Basic-(VBA)-Funktion für Kalkulations-Programme
C/C++ Berechnung der Bernoulli-Zahlen mit C/C++
Javascript Live-Berechnung der Bernoulli-Zahlen in jeder beliebigen Webseite
Perl Berechnung der Bernoulli-Zahlen mit Perl, speziell für große Zahlen

Bernoulli-Zahlen

Quelle: Wikipedia (modif.)

Jakob Bernoulli

(164-1705) stammte wie zahlreiche andere große Mathematiker und Physiker aus der Familie Bernoulli.
Er lebte in der Schweiz und war durch Korrespondenz und Reisen in persönlichem Kontakt mit allen bedeutenden Wissenschaftern seiner Zeit.
Er führte viele grundlegende Arbeiten auf den Gebieten der Statistik, Infinitesimal-Rechnung und Potenzreihen durch.

Bei der Untersuchung von Potenzreihen stieß er u.a. auf die nach ihm benannte (konstante) Folge von Bruchzahlen. Sie wurden erst nach seinem Tod 1713 publiziert. Die Bernoulli-Zahlen spielen u.a. eine Rolle bei der → Reihen-Entwicklung von triginometrischen (Winkel)-Funktionen.

Leonhard Euler (1707-1783) hatte persönlichen Kontakt mit mehreren Wissenschaftern der Familie Bernoulli. Er fand u.a. die hier vorgestellten Algorithmen und die mit den Bernoulli-Zahlen verwandte konstante Folge der Euler-Zahlen.

Die Berechnung der Bernoulli-Zahlen war vermutlich das historisch erste Computer-Programm: Ada Lovelace beschreibt 1842 einen Algorithmus zur Berechnung der Bernoulli-Zahlen auf der mechanischen Rechenmaschine von Charles Babbage.

Die 'Bernoulli-Zahlen' werden auf dieser Seite lediglich aus Sicht der Informatik vorgestellt. Es besteht ausdrücklich keinerlei Anspruch auf mathematische Exaktheit.

Die Folge der Bernoulli-Zahlen B
1, -1/2, 1/6, 0, -1/30, 0, 1/42, 0, -1/30, 0, 5/66, 0, -691/2730, ...
Die Folge wird manchmal in kompakter Form Bq so dargestellt:
1/6, 1/30, 1/42, 1/30, 5/66, 691/2730, 7/6, 3617/510, 43867/798, ...

Defnition

In der Literatur sind mehrere nahe verwandte Definitionen üblich, die jedoch nicht immer deutlich unterschieden werden.
Wenn es keine Hinweise auf die verwendete Version gibt, muss man notfalls probeweise rechnen. Da sich die Elemente der beiden Folgen schon anfangs deutlich unterscheiden, ist das meistens ein geringes Problem.
Zur Unterscheidung werden hier die Variablen-Namen B bzw Bq (B-quer) verwendet.

Definition von B
x / (e^x-1) = 1 + B[1]*(x)/(1!) + B[2]*(x^2)/(2!) + ... + B[2n]*(x^(2n))/((2n)!)
für |x| < 2pi bzw. -2pi<...x...>+2pi
Diese Definition ergibt die in der Tabelle (nächster Absatz rechts) als B[k] angeführten Werte (ohne Gewähr).
Die ungeraden Elemente k=3,5,7... sind =0, die geraden Elemente wechseln jeweils das Vorzeichen.

Definition von Bq
x / (e^x - 1) = 1 - x/2 + Bq[1]*(x^2)/(2!) - Bq[2]*(x^4)/(4!) ... +- (-1)^(n+1)* Bq[n] * (x^(2*n))/((2*n)!)
für |x| < 2pi bzw. -2pi<...x...>+2pi
Diese Definition ergibt die in der Werte-Tabelle als Bq[k] angeführten Werte (ohne Gewähr).

Auffällig sind u.a. die Unterschiede schon zwischen der deutschen und der englischen Version der Wikipedia-Seiten zu diesem Thema.

Zwischen den beiden Versionen der Bernoulli-Zahlen besteht der Zusammenhang
Bq[k] = (-1)^(k+1) * B[2k]
für k=1,2,3...
Wikipedia: Bernoulli-Zahl (de), (en), Euler'sche Zahlen, Euler-Zahlen (Dreieck), Jakob Bernoulli, Leonhard Euler, Julius Worpitzky MathWorld / Wolfram: Bernoulli Number, Bernoulli Polynomial, Euler Number, Eulers Number Triangle, Euler Polynomial

Werte-Liste der Bernoulli-Zahlen

Die Tabelle gibt die Zahlenwerte der ersten Elemente der Bernoulli-Zahlen an (ohne Gewähr). Wie üblich werden sie als Bruchzahlen angegeben, das erlaubt die absolut exakte Berechnung.
Wenn man mit üblichen Gleitkomma-Zahlen der Type 'Double Precision' rechnet, dann reduziert sich die → Genauigkeit auf ca. 15 Dezimalstellen.
Die Werte der beiden ersten Bernoulli-Zahlen B[0] und B[1] ergeben sich aus der mathematischen Ableitung, nicht aus den hier vorgestellten Formeln. Sie werden ohne Berechnung fix eingetragen.
Die weiteren Elemente von B ergeben sich sinngemäß, d.h. B[31]=0 und B[32]=-Bq[16]=-7709321041217/510 usw.

kB[k]Bq[k]
011 / 20.5
1-1 / 21 / 6 0.1666666666666666666666666666666666666667
2+1 / 61 / 30 0.03333333333333333333333333333333333333333
301 / 42 0.02380952380952380952380952380952380952381
4-1 / 301 / 30 0.03333333333333333333333333333333333333333
505 / 66 0.07575757575757575757575757575757575757576
6+1 / 42691 / 2730 0.2531135531135531135531135531135531135531
707 / 6 1.166666666666666666666666666666666666667
8-1 / 303617 / 510 7.092156862745098039215686274509803921569
9043867 / 798 54.97117794486215538847117794486215538847
10+5 / 66174611 / 330 529.1242424242424242424242424242424242424
110854513 / 138 6192.12318840579710144927536231884057971
12-691 / 2730236364091 / 2730 86580.25311355311355311355311355311355311
1308553103 / 6 1425517.166666666666666666666666666666667
14+7 / 623749461029 / 870 27298231.06781609195402298850574712643678
1508615841276005 / 14322 601580873.9006423683843038681748359167714
16-3617 / 5107709321041217 / 510 15116315767.09215686274509803921568627451
1702577687858367 / 6 429614643061.1666666666666666666666666667
18+43867 / 79826315271553053477373 / 1919190 13711655205088.33277215908794856163277216
1902929993913841559 / 6 488332318973593.1666666666666666666666667
20-174611 / 330261082718496449122051 / 13530 19296579341940068.14863266814486326681449
2101520097643918070802691 / 1806 841693047573682615.0005537098560354374308
22854513 / 13827833269579301024235023 / 690 40338071854059455413.07681159420289855072
230596451111593912163277961 / 282 2115074863808199160560.145390070921985816
24-236364091 / 27305609403368997817686249127547 / 46410 120866265222965259346027.3119370825253178
250495057205241079648212477525 / 66 7500866746076964366855720.075757575757576
26+8553103 / 6801165718135489957347924991853 / 1590 503877810148106891413789303.0522012578616
27029149963634884862421418123812691 / 798 36528776484818123335110430842.97117794486
28-23749461029 / 8702479392929313226753685415739663229 / 870 2849876930245088222626914643291.067816092
29084483613348880041862046775994036021 / 354 238654274996836276446459819192192.1497175
308615841276005 / 143221215233140483755572040304994079820246041491 / 56786730 21399949257225333665810744765191097.39267
Die folgenden Kapitel stellen einige Möglichkeiten vor, um mit eigenen Mitteln beliebige Elemente der Bernoulli-Zahlenfolge zu berechnen. Die Daten wurden mit dem unten vorgestellten ↓ Perl-Programm berechnet. An den Bruchstrichen wurden Leerzeichen eingefügt. Die Gleitkommazahlen wurden auf 40 Dezimal-Stellen gerundet.

Algorithmen zur Berechnung der Bernoulli-Zahlen

Es gibt mehrere numerische Verfahren zur Berechnung der Bernoulli-Zahlen. In den folgenden Kapiteln wurde versucht, den jeweils zur Methode passenden Algorithmus vorzustellen. Wenn beide Folgen B und Bq angegeben sind, dann wird meist Bq berechnet und daraus B abgeleitet.

Algorithmen zur Reihen-Entwicklung

Dieser Algorithmus zur Berechnung der B Folge stammt von Leonhard Euler: Er berechnet nur die geraden Elemente, alle ungeraden setzt man =0
Quelle: Wikipedia
Alle weiteren Beispiele dieser Seite verwenden für B diesen Algorithmus.

Dieser Algorithmus berechnet die Bq[n] Folge, d.h. nur positive Zahlenwerte >0
Quelle: Wikipedia

Die Algorithmen verwenden eine Konstante und zwei Funktionen, die nicht in jeder Anwendung verfügbar sind:
Berechnung der → Kreiszahl Pi durch Reihen-Entwicklung
Für Potenzierung und → Fakultät-Funktion kann man eigene Hilfsprogramme einsetzen.
Alle vorgestellten Hilfsprogramme erfordern lediglich die 4 Grundrechnungs-Arten und keine weiteren Funktionen.

Alternative Reihen-Entwicklung:
Bq[k] = summe * ((2k)!) / (pi^(2k)*(2^(2k-1)-1))
summe = 1 - 1/(2^(2k)) + 1/(3^(2k)) - 1/(4^(2k)) ... +- 1/(n^(2k))
Funktioniert ähnlich, erfordert jedoch zusätzlich die Programmierung des alternierenden Vorzeichens der Reihen-Elemente.

Alternative Reihen-Entwicklung:
Bq[k] = summe * (2*(2k)!) / (pi^(2k)*(2^(2k)-1))
summe = 1 + 1/(3^(2k)) + 1/(5^(2k)) + 1/(7^(2k)) + ... + 1/((2n-1)^(2k))
Funktioniert ähnlich, scheint jedoch keine Vorteile zu bieten.

Die englische Wiki-Version erwähnt eine Reihe weiterer Alternativen zur effizienten numerischen Berechnung.

Einige Medien berichteten 2009 über die Entdeckung einer neuen, einfachen Formel durch den damals 16jährigen Mohamed Altoumaimi. Dabei scheint es sich jedoch um einen Irrtum zu handeln, denn abgesehen von einer netten Story findet man diese Formel leider nirgends. Auch die angebliche Unfähigkeit schwedischer Mathematik-Lehrer, die Formel zu berechnen, ist vielleicht nur eine späte Rache der JournalistInnen...

Rekursions-Algorithmus

Es ist möglich, jede Bernoulli-Zahl B[k] ab k>1 aus allen vorhergehenden Bernoulli-Zahlen B[0]...B[k-1] zu berechnen:
Die beiden ersten Bernoulli-Zahlen werden explizit eingesetzt (Ausnahmen von der Formel):
B[0] = 1
B[1] = -1/2

Alle folgenden ungeraden Bernoulli-Zahlen B[2n+1] werden =0 gesetzt.

Alle folgenden geraden Bernoulli-Zahlen B[2n] werden nach der angegebenen Summen-Formel berechnet. Dazu benötigt man die → Binomial-Koeffizienten 'm über k' oder in der hier verwendeten Schreibweise (m|k)

Auf dieser Seite wird ein Programm in der ↓ Programmiersprache Perl vorgestellt, welches diesen Algorithmus zur exakten Berechnung beliebig vieler Elemente der Bernoulli-Zahlen verwendet.

Bernoulli-Zahlen mit einem Kalkulations-Programm

Mit jedem gängigen Kalkulations-Programm kann man die Bernoulli-Zahlen berechnen, z.B. mit LibreOffice-Calc, OpenOffice-Calc, MS-Excel, ...

Kalkulations-Dateien sind in alle Betriebssysteme und mindestens in das Programm LibreOffice portabel.
Das vorgestellte Beispiel hat allerdings eher didaktische Bedeutung, da man in der Praxis meist nur die ersten Bernoulli-Zahlen verwendet, und diese nicht mit Iteration sondern aus den ↑ tabellierten Bruchzahlen berechnet.

Wenn sie Formel-Texte von diesem Beispiel in ein Kalkulations-Programm kopieren, dann müssen sie allfällige führende Leerzeichen (vor den = Zeichen entfernen !

Kalkulations-Programm für B[k]

Der Index k wird in Zelle B1 manuell vorgegeben. Tragen sie hier nur ganzzahlige Werte k>0 ein, z.B. k=1,2,3,4 ...

Das Ergebnis B[2k] wird in der darunter liegenden Zelle B2 berechnet. Die ungeraden Elemente werden nicht berechnet, sie sind alle =0

Hilfs-Variable:
Der im Kapitel ↑ oberhalb angegebene Algorithmus wird sinnvoll in einige Teile zerlegt, die sich einzeln viel übersichtlicher berechnen lassen:
Die Variablen 2*k, f0, f1, f2 werden unabhängig von der Länge der berechneten Reihe nur 1mal berechnet.

Reihe
In den Zeilen 11...110 werden die ersten 100 Elemente der Reihe berechnet. Man kann die Formeln ab A12:C12 bequem nach unten ausfüllen - hier bis zum Element k=100
In C11:C110 wird die laufende Summe der Reihe berechnet. Die letzte Summe aus Zelle C110 wird zur Berechnung des Gesamt-Ergebnisses in Zelle B8 übertragen.
   ABC
1k3 
2 ="B["&B4&"]" =B5*B6/B7*B8  
3   
42*k=2*B1 
5f0=(-1)^(B1+1) 
6f1 =2*FAKULTÄT(B4)  
7f2=(2*PI())^B4 
8sum=C110 
9                 
10nel[n]sum
111=1/A11^$B$4=B11
12=A11+1=1/A12^$B$4=C11+B12
13=A12+1=1/A13^$B$4=C12+B13
...
110=A109+1=1/A110^$B$4=C109+B110

Kalkulations-Programm für Bq[k]

Der Index k wird in Zelle B1 manuell vorgegeben. Es sind nur ganzzahlige Werte k>0 zulässig, z.B. k=1,2,3,4 ...

Das Ergebnis Bq[k] wird in der darunter liegenden Zelle B2 berechnet.

Hilfs-Variable:
Der im Kapitel ↑ oberhalb angegebene Algorithmus wird sinnvoll in einige Teile zerlegt, die sich einzeln viel übersichtlicher berechnen lassen:
Die Variablen 2*k, f1, f2 werden unabhängig von der Länge der berechneten Reihe nur 1mal berechnet.

Reihe
In den Zeilen 10...109 werden die ersten 100 Elemente der Reihe berechnet. Man kann die Formeln ab A11:C11 bequem nach unten ausfüllen - hier bis zum Element k=100
In C10:C109 wird die laufende Summe der Reihe berechnet. Die letzte Summe aus Zelle C109 wird zur Berechnung des Gesamt-Ergebnisses in Zelle B7 übertragen.
   ABC
1k3 
2 ="Bq["&B1&"]" =B5/B6*B7 
3   
42*k=2*B1 
5f1=FAKULTÄT(B4) 
6f2=PI()^B4*2^(B4-1) 
7sum=C109 
8                 
9nel[n]sum
101=1/A10^$B$4=B10
11=A10+1=1/A11^$B$4=C10+B11
12=A11+1=1/A12^$B$4=C11+B12
...
109=A108+1=1/A109^$B$4=C108+B109

Ergebnisse

Der Algorithmus zur Berechnung der ersten Bernoulli-Zahlen konvergiert nur sehr langsam. Man muss die Reihe vorzeitig abbrechen (im Beispiel bei k=100) und auf Genauigkeit verzichten.

Bei der praktischen Anwendung der Bernoulli-Zahlen gehen jedoch gerade die ersten Bq[1]...Bq[5] mit dem größten Gewicht ein: Daher ist gerade dort der Verzicht auf Genauigkeit besonders unangenehm.
Deshalb ist eine praktische Lösung sinnvoll und empfehlenswert: Man verwendet für die ersten Bernoulli-Zahlen die tabellierten Bruchzahlen, insbesondere Bq[1]=1/6

Alle anderen Bernoulli-Zahlen lassen sich allgemein mit dem angegebenen ↑ Algorithmus (oder einer Variante) rasch berechnen, ab B[4] mit <100 Schritten, ab Bq[9] mit <10 Schritten.

knmax
1>1E8
29741
3457
499
540
622
714
810
98
107
153
162

Tabelle: Anzahl von Iterations-Schritten bis zur maximalen Genauigkeit (Double):
Die ersten Elemente k<4 werden besser aus den tabellierten Bruchzahlen berechnet.

Ab k=16 wird die Reihe mit der üblichen Double- → Genauigkeit nicht mehr berechnet:
Das erste Element wird immer =1.
Alle weiteren Elemente sind <5E-15 so klein, dass sich die Summe der Reihe nicht mehr ändert.

Tipp: Erzeugen sie ein XY-Diagramm mit x=k und y=ln(Bq[k])

Bernoulli-Zahlen mit Basic (LibreOffice-Basic, Visual Basic, VBA)

Ein Interpreter der Programmiersprache → Basic ist in jedem gängigen Kalkulations-Programm enthalten (LibreOffice, OpenOffice, MS-Excel, ...). Man braucht keine zusätzlichen Hilfsmittel, um das Beispiel selbst zu programmieren, oder den Beispiel-Text in LibreOffice-Basic bzw. in ein Excel-VBA-Modul einzusetzen. Sowohl die Kalkulations-Dateien als auch der hier vorgestellte Basic-Quelltext ist in alle gängigen Betriebssysteme und mindestens in das Kalkulations-Programm LibreOffice-Calc portabel.
Details zur Verwendung von Basic-Funktionen mit Kalkulations-Programmen.

Programmierung mit Basic


Argumente:
Die Funktion my_bernoulli_q() akzeptiert 1 Argument:
k ... Index der zu berechnenden Bernoulli-Zahl, als ganze Zahl>0

Tabellierte Bruchzahlen
Die Berechnung der ersten Bernoulli-Zahlen ist mit Reihen-Entwicklung ungünstig (langsam, für k=1 auch ungenau). Diese werden daher aus den tabellierten Bruchzahlen berechnet: Die Select-Anweisung bewirkt je nach dem Index k eine Mehrfach-Verzweigung: Die Fälle k=1 bis k=3 werden rasch und genau aus den Bruchzahlen berechnet, alle weiteren k>3 mit Reihen-Entwicklung.

Schleife
Mit der Anweisung Case Else beginnt die Reihen-Entwicklung für jeden Index k>3
Die Hilfs-Variablen k2,f1,f2 werden vor Beginn der Schleife nur 1mal berechnet. Die laufende Summe der Elemente wird auf den Anfangswert sum=0 gesetzt.
In jedem Schleifen-Durchlauf wird 1 Element der Reihe berechnet.

Innerhalb der Schleife wird der zuletzt berechnete Wert der Summe in der Variablen vsum gespeichert. Danach wird ein Element der Reihe berechnet und zur laufenden Summe addiert.
Zur Sicherheit wird ein Schleifen-Zähler n geführt, mit dem die Schleife garantiert abgebrochen wird. Im Beispiel genügen maximal 100 Elemente zur Berechnung aller Bernoulli-Zahlen B[>3] mit maximaler Genauigkeit.
Die Schleife wird wiederholt, so lange sich das neu berechnete Ergebnis sum vom vorherigen vsum unterscheidet.

Abbruch:
Wenn sich das Ergebnis der Reihen-Entwicklung nicht mehr ändert, oder wenn der Schleifen-Zähler n die programmierte Grenze (hier 100) erreicht hat, wird die Schleife mit doloop=False abgebrochen.
Danach wird das Ergebnis aus der Summe der Reihe sum und den beiden Hilfs-Variablen f1, f2 berechnet und zurückgegeben.

Hilfs-Funktionen:
Die vorgestellte Funktion verwendet die Konstante pi sowie den Potenz-Operator ^ und als Ersatz der Fakultät-Funktion die ↓ Hilfs-Funktion my_factorial()
Die Konstante (Kreiszahl) Pi kann man bei Bedarf ebenfalls als → Reihe berechnen, den Potenz-Operator durch eine eigene ↓ Hilfs-Funktion my_pow() ersetzen. Damit lässt sich die gesamte Rechnung lediglich mit Hilfe der 4 Grundrechnungs-Arten ausführen.

Berechnung der Bernoulli-Zahlen Bq[k] als Basic-Funktion:
Option Explicit
Const pi = 3.14159265358979

Function my_bernoulli_q(kq As Integer) As Double
Dim doloop As Boolean
Dim k2, n As Integer
Dim bq, f1, f2, sum, vsum As Double
Select Case kq
Case 0
bq = 1 / 2
Case 1
bq = 1 / 6
Case 2
bq = 1 / 30
Case 3
bq = 1 / 42
Case Else
k2 = 2 * kq
f1 = my_factorial(k2)
f2 = (pi ^ k2) * (2 ^ (k2 - 1))
sum = 0
n = 1
doloop = True
While (doloop)
vsum = sum
sum = sum + 1 / (n ^ k2)
n = n + 1
If (vsum = sum Or n > 100) Then
doloop = False
End If
Wend
bq = sum * f1 / f2
End Select
my_bernoulli_q = bq
End Function

Die Berechnung aus tabellierten Bruchzahlen lässt sich beliebig ausweiten, z.B. mit
Case 4
bq = 1 / 30
Case 5
bq = 5 / 66
Case 6
bq = 691 / 2730
Case 7
bq = 7 / 6
usw. (siehe ↑ Liste)

Anwendung

Die Basic-Funktion kann man als 'Benutzerdefinierte Funktion' in jeder beliebigen Zelle eines Kalkulations-Programms verwenden.

Das Beispiel berechnet in Spalte A die Index-Zahlen 1...20 und in Spalte B die jeweiligen Bernoulli-Zahlen. Man kann die Formeln ab A3:B3 nach unten ausfüllen.
Berechnung der Bernoullli-Zahlen mit Basic-Funktion:
   AB
1k Bq[k]
21 =my_bernoulli_q(A2)
3=A2+1 =my_bernoulli_q(A3)
4=A3+1 =my_bernoulli_q(A4)
...
21=A20+1 =my_bernoulli_q(A21)

Berechnung der B mit Basic

Diese Funktion berechnet im Gegensatz zum ↑ Kalkulations-Programm sowohl die geraden als auch die ungeraden Elemente von B

Die Anweisung Select Case kq verzweigt je nach dem Argument k zu den tabellierten Werten für k=0 und k=1 oder zum Algorithmus Case Else

Der folgende Algorithmus benutzt die ↑ oben vorgestellte Basic-Funktion my_bernoulli_q() zur Berechnung aller anderen Bq

Die bedingte Verzweigung if(k Mod 2) prüft mit Hilfe des → Modulo-Operators, ob das Argument k gerade oder ungerade ist.

Für alle ungeraden k wird das Ergebnis b=0 gesetzt.

Für alle geraden k wird die Basic-Funktion my_bernoulli_q() mit dem halben Index kq=k/2 verwendet.
Anschließend wird für alle geraden kq das Vorzeichen umgekehrt.

Anwendung

Diese benutzerdefinierte Funktion ist genauso anzuwenden wie für die ↑ Funktion my_bernoulli_q() beschrieben.

Berechnung der Bernoulli-Zahlen B[k] als Basic-Funktion:
Function my_bernoulli(k As Integer) As Double
Dim kq As Integer
Dim b As Double
Select Case k
Case 0
b = 1
Case 1
b = -1 / 2
Case Else
If (k Mod 2 = 0) Then
kq = k / 2
b = my_bernoulli_q(kq)
If (kq Mod 2 = 0) Then
b = -b
End If
Else
b = 0
End If
End Select
my_bernoulli = b
End Function
Basic (LibreOffice-Basic, Visual Basic, VBA) Hilfs-Funktion my_pow() zur Berechnung der Potenz-Funktion.

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

Anwendung:
x_hoch_y = my_pow(x,y)
Basic (LibreOffice-Basic, Visual Basic, VBA) Hilfs-Funktion my_factorial()
Private Function my_factorial( _
ByVal number As Integer) _
As Double
Dim i As Integer
Dim f As Double
f = 1
For i = 1 To number
f = f * i
Next
my_factorial = f
End Function

Anwendung:
x_fakultaet = my_factorial(x)

Bernoulli-Zahlen mit C/C++

Die Programmiersprache → C/C++ wird für Sonder-Aufgaben eingesetzt, die eine besonders schnelle Ausführung erfordern.

Noch schneller - aber vom jeweiligen Prozessor abhängig - sind nur Programme in Maschinensprache (Assembler).
Man benötigt ein spezielles Programme (Compiler) zur Umwandlung des Quelltextes (SourceCode) in ein ausführbares Programm.
Die ausführbaren Programme (binaries, *.exe) sind nicht portabel, d.h. man muss ein C/C++ Programm eigens für jedes Betriebssystem, teilweise auch für System-Versionen herstellen (compilieren).
Alle gängigen Linux-Systeme enthalten einen C/C++ Compiler oder können ihn mit Mausklick laden.
Für Windows kann man u.a. → CodeBlocks verwenden.

Programmierung mit C/C++


Vor Beginn der eigentlichen Programme werden die verwenden Funktionen und die Konstante PI (Kreiszahl) deklariert / definiert.

Das Haupt-Programm main() enthält lediglich eine Schleife, in welcher die jeweilige Bernoulli-Zahl berechnet und → ausgegeben wird.
Zur Berechnung wird in jedem Durchgang der Schleife die Funktion my_bernoulli() aufgerufen.

Die Programmierung der Funktion my_bernoulli() folgt allen anderen auf dieser Seite vorgestellten Beispielen:

Die Anweisungen switch - case - default verzweigen je nach dem Wert des Arguments k zur direkten Berechnung mit Hilfe der tabellierten Bruchzahlen (k=1...3) oder zur Berechnung mit Reihen-Entwicklung (k>3).

Ganzzahlige Werte werden bei Bedarf mit dem vorangestellten Operator (double) in Gleitkomma-Zahlen umgewandelt. Das ist sicher, aber nicht immer notwendig, da die Standard-Funktionen in C++ überladen sind und auch int Argumente akzeptieren.

Zur Potenzierung wird die Standard-Funktion pow() der Bibliothek <math.h> verwendet, für die → Fakultät-Funktion die selbst programmierte Hilfs-Funktion my_factorial()

Die Fakultät-Funktion kann mit den oft dazu vorgestellten ganzzahligen Funktionen nur bis 16! rechnen !
Gleitkomma-Typen (double) haben einen größerem Werte-Bereich, damit kann man immerhin bis 170! rechnen.

Das Beispiel-Programm erzeugt lediglich eine wenig spektakuläre Ausgabe auf einer → Konsole (Linux-Shell, Windows cmd.exe ).
Die Funktion lässt sich jedoch problemlos auf jedes andere C/C++ Programm übertragen.
Berechnung der Bernoulli-Zahlen mit der Programmiersprache C/C++, z.B. mit dieser kompletten C-Quelltext-Datei bernoulli.cpp
#include <stdio.h>
#include <math.h>

double my_bernoulli(int);
double my_factorial(int);
// double my_pow(double,int);

const double PI=3.14159265358979;

int main() {
int k;
double bk;
for(k=1;k<=20;k++) {
bk = my_bernoulli(k);
printf("B[%2d] = %f\n",k,bk);
}
return 0;
}

double my_bernoulli(int k) {
int doloop,k2,n;
double b,f1,f2,sum,vsum;
switch(k) {
case 1: b=1.0/6.0; break;
case 2: b=1.0/30.0; break;
case 3: b=1.0/42.0; break;
default:
k2 = 2 * k;
f1 = my_factorial(k2);
f2 = pow(PI,(double)k2) * pow(2.0,(double)(k2-1));
sum = 0.0;
n = doloop = 1;
while(doloop) {
vsum = sum;
sum += 1/pow((double)n,(double)k2);
n++;
if(vsum==sum || n>100) {doloop=0;}
}
b = sum * f1 / f2;
}
return b;
}

double my_factorial(int n) {
if (n==1) {return 1.0;}
else{return my_factorial(n-1) * (double)n;}
}
Man kann auch die die Potenz-Funktion (rechts) selbst programmieren.
In diesem Fall braucht man auch die Bibliothek <math.h> nicht mehr und kann die gesamte Aufgabe lediglich mit den 4 Grundrechnungs-Arten berechnen.
Ersetzen sie in Funktion my_bernroulli() den Aufruf von pow() durch my_pow() und entfernen sie die führenden // Kommentar-Zeichen von der Deklaration der Funktion.
double my_pow(double b,int ie) {
int i;
double p=1;
for(i=0;i<ie;i++) {p*=b;}
return p;
}

Bernoulli-Zahlen mit Javascript

Live Berechnung

Die Tabelle rechts wurde von ihrem Browser unmittelbar nach dem Laden der Webseite Live berechnet. Die dazu aufgewendete Zeit ist meist zu klein für eine Messung, jedenfalls unerheblich.

Ein Javascript-Interpreter ist in jedem gängigen Browser enthalten. Man braucht daher zur Ausführung der Programme keine zusätzlichen Resourcen.

Javascript-Programme sind portabel, d.h. die Webseiten inkl. der darin enthaltenen Javascript-Programme funktionieren auf allen gängigen Betriebssystemen und mit allen gängigen Browser-Programmen.

Der Quelltext jeder Webseite besteht aus einfachem lesbarem Text. Man kann ihn daher mit jedem Text-Editor bearbeiten, z.B. auf Windows mit notepad.exe, besser mit Notepad++ (professionell, kostenfrei).
 k B[k]Bq[k]

Sie haben vermutlich die Verwendung von Javascript durch ihren Browser abgeschaltet.
Daher funktioniert weder die Live-Berechnung der Bernoulli-Zahlen, noch irgendeine andere der zahlreichen Live-Funktionen dieses Webs.
Das Programm folgt allen anderen auf dieser Seite vorgestellten Beispielen:

Die Anweisungen switch - case - default verzweigen je nach dem Wert des Arguments k zur direkten Berechnung mit Hilfe der tabellierten Bruchzahlen (k=1...3) oder zur Berechnung mit Reihen-Entwicklung (k>3).

Zur Potenzierung wird die Standard-Funktion Math.pow() verwendet, für die Fakultät-Funktion die selbst programmierte ↓ Hilfs-Funktion my_factorial()

In dieser Webseite wird die Funktion von einer anderen Javscript-Funktion do_bernoulli() aufgerufen, welche mit Hilfe von → DOM-Methoden die Tabelle erzeugt.

Die Funktion wird auch von der ↓ Javascript-Funktion my_bernoulli() verwendet.
Berechnung der Bernoulli-Zahlen Bq[k] als → Javascript-Funktion:
function my_bernoulli_q(kq) {
var bq=0;
switch(kq) {
case 1: bq = 1/6; break;
case 2: bq = 1/30; break;
case 3: bq = 1/42; break;
default:
var k2 = 2 * kq;
var f1 = my_factorial(k2);
var f2 = Math.pow(Math.PI,k2) * Math.pow(2,(k2-1));
var sum=0; var vsum=0;
var n = 1;
var doloop = true;
while(doloop) {
vsum = sum;
sum += 1 / Math.pow(n,k2);
n++;
if(vsum==sum || n>100) {doloop = false;}
}
bq = sum * f1 / f2;
}
return bq;
}
Das Programm berechnet sowohl die geraden als auch die ungeraden Elemente der Folge B

Die bedingte Verzweigung if(k % 2) prüft mit Hilfe des → Modulo-Operators, ob das Argument k gerade oder ungerade ist.

Für alle ungeraden k bleibt das Ergebnis b=0

Für alle geraden k wird die im Absatz oberhalb vorgestellte Funktion my_bernoulli_q() mit dem halben Index kq=k/2 verwendet.
Anschließend wird für alle geraden kq das Vorzeichen umgekehrt.
Berechnung der Bernoulli-Zahlen Bq[k] als → Javascript-Funktion:
function my_bernoulli(k) {
var b=0;
switch(k) {
case 0: b=1; break;
case 1: b=-1/2; break;
default:
if(!(k % 2)) {
var kq = k / 2;
b = my_bernoulli_q(kq);
if(!(kq % 2)) {b=-b;}
}
}
return b;
}
Javascript Hilfs-Funktion my_pow() zur Berechnung der Potenz-Funktion
function my_pow(b,ie) {
var p=1;
for(var i=1;i<=ie;i++) {p*=b;}
return p;
}
Anwendung in Javascript:
x_hoch_y = my_pow(x,y);
Javascript Hilfs-Funktion my_factorial() zur Berechnung der → Fakultät-Funktion (bis maximal n<=170).
function my_factorial(n) {
var f=1;
for(var i=1;i<=n;i++) {f*=i;}
return f;
}
Anwendung in Javascript:
n_fakultaet = my_factorial(n);

Bernoulli-Zahlen mit Perl

Die Programmiersprache → Perl bietet mit dem → Modul Math::Big die Möglichkeit, beliebige Bernoulli-Zahlen exakt zu berechnen, oder - besonders bequem - die ersten 40 Bernoulli-Zahlen mit einer Funktion direkt anzugeben. Perl ist eine moderne Interpreter-Programmiersprache, die inbesondere bei fortgeschrittenen EntwicklerInnen und im wissenschaftlichen Bereich sehr populär ist. In jeder gängigen Linux-Distribution ist ein Perl-Interpreter enthalten. Auf Windows kann man Perl kostenfrei selbst installieren (Details)

Funktion   bernoulli()

Die Funktion bernoulli() aus dem Perl-Modul Math::Big berechnet die ersten 40 Bernoulli-Zahlen mit absoluter Genauigkeit der Bruchzahlen.

Bei Angabe eines einzelnen (skalaren) Rückgabe-Werts (hier $b) gibt die Funktion eine Gleitkomma-Zahl zurück.

Bei Angabe einer Liste gibt die Funktion Zähler und Nenner der Bernoulli-Bruchzahl zurück (hier $c,$d).
Ein komplettes Perl-Programm zur Berechnung der ersten 40 Bernoulli-Zahlen, z.B. als Text-Datei bernoulli_1.pl
#!/usr/bin/perl
use strict;
use Math::Big qw/bernoulli/;
my($b,$k,$n,$z);
for($k=0;$k<=40;$k++) {
($z,$n) = bernoulli($k);
print "Bernoulli[$k] = $z/$n";
$b = bernoulli($k);
print " = $b \n";
}
Die Perl-Funktion bernoulli() gibt die B Daten zurück, d.h. für alle geraden Elemente (mit Ausnahme von n=0) ist B[n]=0 und für alle ungeraden Elemente wechselt jeweils das Vorzeichen.
Ausgabe:
Bernoulli[0] = 1/1 = 1
Bernoulli[1] = -1/2 = -0.5
Bernoulli[2] = 1/6 = 0.1666...
Bernoulli[3] = 0/1 = 0
Bernoulli[4] = -1/30 = -0.0333...

Rekursions-Algorithmus

Dieser Algorithmus ist sinnvoll, wenn man mehrere Bernoulli-Zahlen braucht, insbesondere zur Berechnung besonders vieler Elemente dieser Folge mit großer Genauigkeit.

Haupt-Programm
Das Programm ist bewusst einfach und kompakt:
Die beiden (kostenfreien) Perl-Module Math::BigInt und Math::BigRat werden eingebunden. Sie erlauben das Rechnen mit ganzen Zahlen und Bruchzahlen beliebiger Größe und mit absoluter Genauigkeit.
Die Anzahl $kmax der zu berechnenden Elemente wird hier im Programm vorgegeben.
Mit der Funktion bca_create() wird das → Array @bca aller benötigten Binomial-Koeffizienten berechnet.
Mit der Funktion ba_create() wird das → Array @ba aller angeforderten Bernoulli-Zahlen berechnet.
Danach folgt die Ausgabe der berechneten Bernoulli-Zahlen in einer for-Schleife.

Funktion bca_create()
Diese Funktion berechnet das 2dimensionale Array @bca aller benötigten Binomial-Koeffizienten. Ein Array-Element $bca[$i][$j] bezeichnet den Koeffizienten 'i über j' oder in der hier verwendeten Darstellung (i|j)
Die Binomial-Koeffizienten werden als 'große' ganze Zahlen mit absoluter Genauigkeit berechnet und gespeichert, d.h. als Strings (!), nicht im internen Ganzzahlen-Format (Integer).
Details zur Berechnung der Binomial-Koeffizienten.

Funktion ba_create()
Diese Funktion berechnet das Array @ba aller angeforderten Bernoulli-Zahlen. Diese werden nach dem oben angegebenen ↑ Rekursions-Algorithmus berechnet und als 'große' Bruchzahlen mit absoluter Genauigkeit gespeichert.

Ausgabe (ohne Titelzeile):
B[0] = 1
B[1] = -1/2
B[2] = 1/6
...
B[100] = -945980.../33330

Die Rechenzeit bis zu B[100] beträgt an einem typischen PC ca. 1 Sekunde, bis B[200] 4s. Für noch mehr Bernoulli-Zahlen nimmt die Rechenzeit deutlich zu: In diesem Fall rechnet man besser nur 1mal und speichert die Ergebnisse in einer Datei.
Ein komplettes Perl-Programm zur Berechnung von Bernoulli-Zahlen, z.B. als Text-Datei bernoulli_2.pl
#!/usr/bin/perl
use strict;
use Math::BigInt;
use Math::BigRat;
print "Bernoulli-Zahlen\n";
my($bc,$bd,$bf,$i,$kmax,@bca,@ba);
$kmax=100;   # Vorgabe
bca_create($kmax);   # Array der Binomial-Faktoren
ba_create($kmax);   # Array der Bernoulli-Zahlen
# Ausgabe
for($i=0;$i<=$kmax;$i++) {
printf(" B[%d] = %s\n",$i,$ba[$i]);
# print " = ".$ba[$i]->as_float(),"\n";
}

sub bca_create {
my($ijmax)=@_;
my($i,$j,$bc);
for($i=0;$i<=$ijmax;$i++) {
for($j=0;$j<=$ijmax;$j++) {
if(!$j) {$bc=1;}
elsif($j>$i) {$bc=0;}
elsif($j==1) {$bc=$i;}
elsif($j>($i/2)) {$bc=$bca[$i][$i-$j];}
else {
$bc=Math::BigInt->new($bca[$i-1][$j]);
$bc->badd($bca[$i-1][$j-1]);
}
$bca[$i][$j]=$bc;
}
}
}

sub ba_create {
my($kmax)=@_;
my($m,$k,$bi);
$ba[0]=Math::BigRat->new('1');
$ba[1]=Math::BigRat->new('-1/2');
for($m=2;$m<=$kmax;$m++) {
$ba[$m]=Math::BigRat->new('0');
if(!($m % 2)) {
for($k=0;$k<$m;$k++) {
$bi=Math::BigRat->new($bca[$m][$k]);
$bi->bmul($ba[$k]);
$bi->bdiv($m-$k+1);
$ba[$m]->bsub($bi);
}
}
}
}

Ausgabe und Anwendung

Bei Verwendung von großen ganzen Zahlen und Bruchzahlen mit dem Modul Math::Big erhält man die Ergebnisse als Strings, d.h. als teilweise sehr lange Ziffern-Ketten.

Es hängt von der Anwendung ab, ob man die Ergebnisse als Strings belassen kann oder umwandeln muss.

String:
Alle Rechen-Funktionen des Moduls Math::Big verwenden zur Ein- und Ausgabe Strings. Zur weiteren internen Verarbeitung verwendet man daher die Ziffern-Strings ohne Umwandlung.
Bei der Ausgabe mit den Funktionen print(), printf(), sprintf() werden Strings verwendet bzw. muss man den Platzhalter %s verwenden (Details).
Rationale Zahlen (Bruchzahlen) werden ohne weitere Maßnahmen auch als solche ausgegeben, d.h. als Zähler, Bruchstrich und Nenner.

Trennung von Bruchzahlen
Das Modul Math::BigRat bietet einige Methoden zur Trennung von Bruchzahlen-Strings in ganzzahlige Zähler- und Nenner-Strings:
$bruch = Math::BigRat->new('3/5');
$zaehler = $bruch->numerator();
$nenner = $bruch->denominator();
# Alternative:
($zaehler,$nenner) = $bruch->parts();


Umwandlung in Gleitkomma:
Das Modul Math::BigRat bietet eine Methode zur direkten Umwandlung in eine 'große' Gleitkomma-Zahl (als String !):
$gleitkomma = $bruch->as_float();
Wenn man mit den erzeugten Gleitkomma-Zahlen auch rechnen will, dann verwendet man zusätzlich das Modul
use Math::BigFloat;
($zaehler,$nenner) = $bruch->parts();
$gleitkomma = Math::BigFloat->new($zaehler);
$gleitkomma->bdiv($nenner);