Eulersche Zahl in C++

Neue Frage »

AstroNerd Auf diesen Beitrag antworten »
Eulersche Zahl in C++
Hallo zusammen smile
Da einige unter euch vermutlich auch Informatiker bzw. Programmierer sind, hätte ich eine kurze Frage, was C++ angeht. Folgender Quelltext soll mir die Eulersche Zahl ausgeben:

#inlcude<iostream>
#include<math.h>
using namespace std;
int main() {
double n;
double e;
for(n=1; n++; ) { e+= pow(1+1/n, n) ;}
cout << "Die Eulersche Zahl ist: " << e;
return 0;
}

Jedoch bekomme ich gerade mal die ersten 5 Nachkommastellen. Wenn ich ein long double verwende gibt er nur Käse aus. Könnte mir evtl. jemand weiter helfen ?
Mit freundlichem Gruß
AstroNerd
IfindU Auf diesen Beitrag antworten »
RE: Eulersche Zahl in C++
Du machst etwas sehr seltsames:
Es gilt
.

Du mischt beides und berechnest .

Unabhängig initialierst du e nicht... D.h. wenn der Compiler das nicht netterweise für dich macht, wird da ein Randomwert rauskommen.

Edit: Sehe gerade, dass deine Schleife nie abbricht...
 
 
10001000Nick1 Auf diesen Beitrag antworten »
RE: Eulersche Zahl in C++
Zitat:
Original von AstroNerd
Jedoch bekomme ich gerade mal die ersten 5 Nachkommastellen.

Wie das? Du hast eine Endlosschleife programmiert, da dürftest du gar keine Ausgabe kriegen.
Wieso initialisierst du eigentlich n als double und nicht als integer?

Zitat:
Original von IfindU
Unabhängig initialierst du e nicht... D.h. wenn der Compiler das nicht netterweise für dich macht, wird da ein Randomwert rauskommen.

Oder er weigert sich, das Programm überhaupt auszuführen (wie Visual Studio). Augenzwinkern
HAL 9000 Auf diesen Beitrag antworten »

Zitat:
Original von 10001000Nick1
Wieso initialisierst du eigentlich n als double und nicht als integer?

Genau. In dem Fall sollte dann in der Rechnung allerdings auch besser 1+1.0/n stehen, oder 1+1/(double)n stehen, oder sicherheitshalber gleich 1.0+1.0/(double)n. Augenzwinkern
Jayk Auf diesen Beitrag antworten »

Der Hammer ist ja: Ich wollte mal zum Spaß das Programm compilieren (g++) um zu schauen, was passiert (weil ich mir nicht vorstellen konnte, dass es tatsächlich irgendeine Ausgabe gibt). Na ja:

Zitat:

euler.cc:1:2: Fehler: ungültige Präprozessordirektive #inlcude
euler.cc: In Funktion »int main()«:
euler.cc:8:1: Fehler: »cout« wurde in diesem Gültigkeitsbereich nicht definiert


Augenzwinkern

Behebt man den offensichtlichen Fehler, kommt wie erwartet eine Endlosschleife.

@AstroNerd: Offensichtlich ist das, was du gepostet hast, nicht der Sourcecode, den du tatsächlich verwendest. Warum schickst du den nicht mal?
AstroNerd Auf diesen Beitrag antworten »

Vielen Dank erstmal für die vielen Antworten.
Nun habe ich ein kleines Nickerchen genommen und den Quelltext überarbeitet (und tatsächlich ist mein geposteter Quelltext nicht ganz der selbe).

#include<iostream>
#include<math.h>
using namespace std;

int main(){
long double n;
long double e;
for (n = 1; n<1000000; n++){ e = pow(1/n + 1 , n);}
cout << "Die Eulersche Zahl ist etwa: " << e ;
cin.sync();
cin.get();
return 0;
}

Wenn eine unendliche Schleife berechnet wird, wird der ,,cout'' Befehl erst erfolgen, wenn die Schleife bis zum Ende berechnet worden ist. Da aber meine Schleife kein Ende hat, wird theoretisch auch niemals der ,,cout'' Befehl ausgeführt. Also habe ich nun eine Obergrenze für das Intervall eingegeben, bekomme jedoch immer noch nur schlappe 5 Nachkommastellen raus. Bei einem höheren Intervall meldet der Compiler, dass die Obergrenze zu groß sei.
Gibt es evtl. eine andere Möglichkeit, mir einige Hundert (oder Tausend) Nachkommastellen ausgeben zu lassen ?
Vielen Dank.
AstroNerd
IfindU Auf diesen Beitrag antworten »

Sieh dir die Definitionen oben von mir an. Die zweite bietet sich deutlich mehr zu numerischen Zwecken an....Wie viele Nachkommastellen du da bekommst weiß ich allerdings nicht (mehr als 5 sicherlich).

Edit: Und du brauchst keine Schleife, wenn du ständig einen neuen Wert errechnest....
10001000Nick1 Auf diesen Beitrag antworten »

Wenn du in deinem Code die Zeile
code:
1:
cout.precision(a);
einfügst, dann werden a Nachkommastellen angezeigt.
HAL 9000 Auf diesen Beitrag antworten »

Zitat:
Original von AstroNerd
Gibt es evtl. eine andere Möglichkeit, mir einige Hundert (oder Tausend) Nachkommastellen ausgeben zu lassen ?

Klar gibt es die, aber sicher nicht auf so naive Weise mit der Verwendung einer double-Variablen (maximal 15-16 Stellen Genauigkeit).

Da braucht man C/C++-Bibliotheken, die mit derart langen Zahlen umgehen können, und außerdem ist da eine numerisch ungünstige Formel - da eignen sich andere um Längen besser, z.B. das schon erwähnte .

EDIT: Ein Beispiel für eine solche Bibliothek ist die GMP.
AstroNerd Auf diesen Beitrag antworten »

Vielen Dank!
Da die Obergrenze jedoch nicht größer sein kann, werden ab der 5. Nachkommastelle keine richtigen Ziffern mehr angegeben :/
Hat jemand noch einen anderen Vorschlag (den Quelltext möglichst simpel und ,,unverändert'' gestalten) ?
AstroNerd Auf diesen Beitrag antworten »

Da mir hier schon angeraten wurde, lieber zu verwenden, habe ich mir überlegt, ob man evtl. darstellen kann, korrigiert mich, falls ich falsch liege:

#include<iostream>
#include<math.h>
using namespace std;

int main(){
long double n;
long double x;
long double sum;
long double prod;
for (n = 1; n<1000000000; n++){ for(x=2; x<n+1;x++){prod *=1/x;} ; sum += (1/prod);}
cout.precision(100);
cout << "Die Eulersche Zahl ist etwa: " << 2+sum ;
cin.sync();
cin.get();
return 0;
}
zyko Auf diesen Beitrag antworten »

Zuerst festlegen, wie genau (Ergebnis) man rechnen will.
Danach durch Abschätzung des Restgliedes der Taylorreihe für ein so festlegen, dass der Rest kleiner als die gewünschte Genauigkeit ist.
Aber aus numerischen Gründen nicht

berechnen sondern rückwärts

berechnen.
Dadurch werden erst alle kleinen Terme aufaddiert und zuletzt die größeren.
Aber auch damit kann nicht beliebig genau gerechnet werden, da die einzelnen Summanden intern bestenfalls (ohne weitere Tricks) double sind.
S. a.
http://de.wikipedia.org/wiki/Intervallarithmetik
Es gibt Intervallarithmetik /Programmiersprachen mit denen nicht nur die Grundrechenarten +, -, *, / sondern auch komplexere Terme mit Genauigkeitsangabe berechnet werden können.
HAL 9000 Auf diesen Beitrag antworten »

Unter Nutzung der genannten GMP könnte ein C++Programm im einfachsten Fall so aussehen:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
#include <iostream>
#include <math.h>
#include <gmpxx.h>
using namespace std;

int main (int argc, char *argv[])
{
    int Digits = 1000;
    if (argc > 1)
    {
        Digits = atoi(argv[1]);
    }
    int BinDigits = (int)(Digits*log(10.0)/log(2.0)+16);
    mpf_set_default_prec(BinDigits);
    mpf_class et = 0;
    mpf_class e = 1;
    mpf_class a = 1;
    for (int n = 1; et != e; n++)
    {
        a /= n;
        et = e;
        e += a;
    }
    mp_exp_t eexp;
    string s = e.get_str(eexp, 10, Digits+2);
    cout << s.substr(0, eexp) << "." << s.substr(eexp, Digits);
    return 0;
}

EDIT: Hab's nochmal überarbeitet, nachdem ich das C++-Interface der GMP gefunden habe - ist so besser lesbar.
Neue Frage »
Antworten »



Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »