eulerische zahl darstellen: iterativ und rekursiv

marvellous

Mitglied
Aufgabe 4: Iteration/Rekursion (ca. 16 Min.)
Die Eulersche Konstante e lässt sich bekanntlich nach einer Reihe entwickeln und
es gilt (n ist der Index eines Reihengliedes):
n= 1 2 3 4 5 6
e=1+(1/1!)+(1/2!)+(1/3!)+(1/4!)+(1/5!)+...


a) Schreiben Sie eine C-Funktion float mye(int n), welche die Zahl e iterativ
berechnet und als Rückgabewert bereitstellt.
Die Berechnung soll so lange erfolgen, bis das n-te Reihenglied in die Berechnung
eingeflossen ist. Die erforderliche Berechnung der Fakultät müssen Sie selbst
durchführen.

float mye(int n)
int k=1;
e=1/k
while(n>1)
{ k=k*n; n--}
return e;
}

könnte die a ungefähr so gehen?









b) Schreiben Sie eine C-Funktion float mye(int n), welche die Zahl e rekursiv
berechnet.
Die Berechnung soll so lange erfolgen, bis das n-te Reihenglied in die Berechnung
eingeflossen ist.
Verwenden Sie für die Berechnung die rekursive Funktion int faku(int n), die
zur Zahl n die Fakultät berechnet. Die Funktion faku() steht Ihnen zur Verfügung,
d.h. Sie müssen diese Funktion nicht selbst programmieren.



bei der b hab ich leider nicht so wirklich ne ahnung..bei ner rekusriven funktion rufen sich die funktionen selbst auf:S bin über jede hilfe dankbar
 
Hast du deine A-Lösung eigentlich einmal ausprobiert?
Das kann man ja nicht einmal kompilieren.

Eine { fehlt, Strichpunkte fehlen und die Variable e (die du per return zurückgeben willst) gibts nicht.

Wenn man das ausgebessert hat und zB 4 übergibt, ist das Ergebnis 24. Nicht Euler.

Zuerst einmal würde ich eine Funktion für die Fakultät schreiben.
Laut Angabe ist die zwar vorgegeben, kann aber trotzdem nicht schaden.

zB:
C++:
int faku(int i)
{
    int e=1;
    while(i>1)e*=(i--);
    return e;
}

Und für die Eulersche Zahl:
C++:
float mye(int i)
{
    float e=0.0;
    for(--i;i>=0;i--)e+=(1/((float)faku(i)));
    return e;
}

Die Angabe verlangt zwar float, aber double wäre hier sinnvoller. Speichert mehr Kommastellen ab.

Gruß
 
Zuletzt bearbeitet:
Hi,

der Vorschlag ist nicht gerade gut. Du kannst in die Taylorentwicklung die Fakultät mit hineinziehen. Wenn du die Fakultät auslagerst, dann wird jedes mal die Funktion faku durchgeführt, obwohl sich nur ein Faktor ändert.

Code:
double mye(int n){
    double k=1;
    double e=1;
    for(int i=1;i<=n;i++){
        k*=i;
        e += 1.0/k;
    }
    return e;
}

Somit wird gleich die Fakultät iterativ mit berechnet. Das geht wesentlich schneller.

zur b) Hier hast du die faku() zur Verfügung.
Code:
int faku(int i)
{
    int e=1;
    while(i>1)e*=(i--);
    return e;
}
Du löst das Problem von hinten. Als Parameter übergibts du den Index des zu berechenden Summanden. Der wird ausgerechnet+taylor(n-1).
Code:
double taylor(int n){
    if(n==1){
        return 2.0;
    }
    return taylor(n-1)+1.0/faku(n);
}
 
Zuletzt bearbeitet:
In der Angabe steht aber, dass man faku verwenden soll...

Wegen dem Performanceverlust beim Funktionsaufruf mach ich mir keine Sorgen, sowas kann der Compiler wegoptimieren.

PS:Aus meinem nicht guten Vorschlag Code rauskopieren kann man? ;-]
 
Zuletzt bearbeitet:
double taylor(int n){
if(n==1){
return 2.0;
}
return taylor(n-1)+1.0/faku(n);
}

ich geh das grad mit nem kumpel durch..der meinte return 1 anstatt 2..wieso return 2?

und wie kann ich das von hand testen bei einer rekursiven funktion?..angenommen ich setz 2 ein für n? wie funktioniert das?
 
naja die Taylor entwicklung ist ja 1 +1 +.....
Stelle 0 und 1 sind fest mit der Eins belegt also brauch man nur bis Stelle 2 rechnen. Ich fang mit Null bei der Nummerierung der Stellen an.

@sheel
In der Angabe steht aber, dass man faku verwenden soll...

Wegen dem Performanceverlust beim Funktionsaufruf mach ich mir keine Sorgen, sowas kann der Compiler wegoptimieren.
Aber nur bei der b). Ich will mich nicht darüber streiten.Die Performance kann bei kleinen Werten nicht so sehr schwanken. Da bin ich nicht deiner Meinung.
PS:Aus meinem nicht guten Vorschlag Code rauskopieren kann man? ;-]
Wie soll man es anders schreiben. Du fängst sogar erst mit den großen Werten beim multiplizieren an, was numerisch gut ist.

@marvellous: per Hand

t(n):= taylor(n)
Code:
t(2)
t(1)                       + 1.0/fac(2)
2.0 +  1.0/fac(1)     + 1.0/fac(2)
Das wird ein haufen Schreibarbeit.
 
Zuletzt bearbeitet:
Na klar ist der Code nicht komplett.
Ich dachte man sollte nur Hilfestellungen bieten.
Da gibt es zwei Möglichkeiten
a) noch ne Bedingung
b) Oder man ändert das n==1 zu n==0 und macht dann auch der 2.0 eine 1.0. Da wird halt noch 1.0/1.0 gerechnet.
 
Zurück