e-Funktion mit Summenschleife programmieren
-
Hallo zusammen. Ich brauche mal eure Hilfe bei einer Aufgabe für mein Informatikpraktikum, das das Programmieren mit C beinhaltet.
Schreiben Sie ein C Programm, das zwei verschiedene Reihen berechnet. Die erste Reihe
(Reihe 1) finden Sie in der Anlage zu dieser Aufgabenstellung. Sie müssen diejenige Reihe
programmieren, die zu Ihrer Matrikelnummer passt, wie in der Anlage angegeben.Die zweite Reihe (Reihe 2) realisiert die Exponentialfunktion mit Hilfe einer
Reihenentwicklung, und zwar mit folgender Summen-Formel:Summe = x^k/k! = 1+x+(1/2)x²+(1/(2*3)) *x³+...
In einer Programmschleife lässt sich xk einfach durch wiederholtes Multiplizieren von x mit einer Variablen realisieren, die den Anfangswert 1.0 bekommen hat (1.0, 1.0*x, 1.0*x*x, 1.0*x*x*x, u.s.w.). k Fakultät (k!) ist das Produkt aller natürlichen Zahlen kleiner und gleich k. Die Berechnung in einer Programmschleife kann mit Hilfe einer Variablen, die in jedem Schleifendurchlauf inkrementiert wird, nach folgendem Schema vorgenommen werden:
1.0, 1.0*1, 1.0*1*2, 1.0*1*2*3, u.s.w.Hinweis: Achten Sie darauf, dass die Variablen für das Bilden von xk und k! und die Variable für die Summenbildung alle den Datentyp double haben! Wenn die Programmausgabe des Summenwerts "inf" oder "nan" anzeigt liegt ein numerisches Problem vor, das wahrscheinlich durch einen zu hohen Wert in einer Integer-Variablen (Überlauf) entstanden ist. Sie sollen die Reihen in jedem Fall ohne
die Verwendung von mathematischen Funktionen, also nur mit Hilfe von Addition, Multiplikation und Division, programmieren!Ihr Programm soll einen Integer-Wert als Benutzereingabe einlesen. Der Eingabewert modulo 100 (Eingabewert % 100) ist die Vorgabe für die Anzahl der Iterationsschritte von Reihe 1. Allerdings sollen Sie dafür sorgen, dass die Anzahl der Iterationsschritte mindestens 5 und höchsten 25 ist. Die errechnete Anzahl muss entsprechend nach unten und oben begrenzt werden.
Nach Abschluss der Berechnung von Reihe 1 soll eine Programmausgabe erfolgen, die
folgende Angaben, in dieser Reihenfolge, enthalten muss:- Ergebniswert der Reihe aus der vorangegangenen Berechnung (Summenwert Reihe1)
- Anzahl der tatsächlich durchgeführten Iterationsschritte
- Idealer Ergebniswert der Reihe für unendlich viele Iterationsschritte (laut Angabe in der Anlage, steht ganz rechts hinter dem Gleichheitszeichen)
Der Ergebniswert der Reihe 1 soll nun der x-Wert (Argumentwert) für die Berechnung der Exponentialfunktion werden. Bevor Sie die Reihe für die Exponentialfunktion berechnen, soll e^x für den Ergebniswert der Reihe 1 ("Reihe1-Wert") durch die Mathematikfunktion exp()ermittelt werden (math.h mit #include einfügen!). Der Wert der Exponentialfunktion aus der C Mathematik-Bibliothek ( exp(Reihe1-Wert) ) soll mit einer Programmausgabe in der
Form "exp(3.567) = 35.410" ausgeben werden (3.567 ist hier nur ein Beispiel für einen Reihe1-Wert).Anschließend sollen Sie die Reihe für die Exponentialfunktion (Reihe 2) programmieren, wie oben beschrieben. Die Schleife soll jedoch nicht eine feste Anzahl von Durchläufen(Iterationen) ausführen, sondern sie soll die Reihe solange fortsetzen, bis ein vorgegebener Fehler unterschritten wird. Dabei wird als idealer Endwert der Iteration der Wert der Exponentialfunktion exp(x) definiert, mit x= Reihe1-Wert. Der Abbruchfehler soll ein Promille von "exp(Reihe1-Wert)" sein. Das heißt, die Schleife soll so lange laufen, wie die
Differenz "exp(Reihe1-Wert) – Summenwert" größer als "exp(Reihe1-Wert)/1000" ist.
Achtung: Als erster Schleifendurchlauf (1. Iterationsschritt) gilt der Reihen-Summand mit
k=1. Im ersten Schleifendurchlauf wird also der Wert von x addiert.Bei jedem Schleifendurchlauf der Reihe 2 sollen der aktuelle Fehler, der aktuelle Summenwert der Reihe und die Anzahl der bisher ausgeführten Iterationen ausgegeben werden. Diese drei Ausgabe-Werte müssen in einer Ausgabezeile stehen. Jeder Schleifendurchlauf muss eine Ausgabezeile erzeugen.
Ich weiß, es ist viel Text. Aber ich wollte euch zeigen, womit ich es zu tun habe.
Also alles was die erste Reihe betrifft ist kein Problem. Das funktioniert super. Mein Problem ist jetzt meine 2. For-Schleife in der nun die e-Funktion aus dem Wert der ersten Reihe berechnet werden soll. Diese bricht nach dem ersten Durchlauf bereits ab, oder die Werte verändern sich nicht. Ich kann es mir nicht genau erklären. Dies sind die Ausgabewerte die ich erhalte wenn ich die Eingabe 666666 (fiktive Matrikelnummer):0.666667
25
0.666667
epx(0.666667)=1.947734
2
fehler: 0.281067
exp2 1.666667
0.001948 <-- Fehlerwert bei dessen Erreichen die Funktion abbrechen sollMan erkennt an dem exp2-Wert, dass nur der erste Schritt der Summenfunktion gerechnet wird und sich ab da die Werte für xk und k wohl nicht mehr ändern.
Dabei müsste die Schleife so lange laufen, bis der erlaubte Fehler, der sich aus der Differenz von dem exp1-Wert - exp2-Wert, einen Wert von exp/1000 erreicht wird. Dies müsste doch mit der Bedingung in meiner for-schleife erfüllt sein, oder nicht? Ich hoffe ihr könnt mir iwie dabei helfen.#include <stdio.h> #include <math.h> int main (void) { int i,n,x,y, minus; long double zaehler=1.0, nenner=1.0; double reihe1, ideal1=0.666667, exp1=1.0; double exp2=1.0, fehler,k=1.0, xk=1.0,e=1.0, f=1.0 ; scanf("%i",&x); x=x % 100 ; if(x<=5) n=5; else if(5<x && x<=25) n=x; else if(x>25) n=25; reihe1= 1.0; minus = 1; for (i=1; i <= n; i++) /*Reihe1*/ { nenner = nenner * 2; if (minus == 1) { reihe1 = reihe1 - zaehler / nenner; minus = 0; } else { reihe1 = reihe1 + zaehler / nenner; minus = 1; } } printf("%f\n%i\n%f\n",reihe1, n, ideal1); exp1=exp(reihe1); printf("epx(%f)=%f\n",reihe1, exp1); /*exp-Wert mit Summenwert der Rehie 1*/ e=exp1/1000; /*Hilfswert, um den zulässigen Fehlerwert zu wissen*/ for(y=1; fehler<e;y++) /*Reihe2 e-Funktion*/ { xk=xk*reihe1; k=k*y; f=xk/k; exp2=1.0+f; fehler=exp1-exp2; } printf("%i\n",y); /*Ausgabe Anzahl der Iterationsschritte*/ printf("fehler: %f\n", fehler); /*Ausgabe Fehler Wert*/ printf("exp2 %f\n%f", exp2, e); /*Ausgabe Summen-e-Wert und Hilfswert */ return 0; }
-
Welchen Wert hat denn
fehler
, wenn du in die Schleife rein gehst?
-
Du berechnest
exp2
falsch.
Die Werte sollen aufaddiert werden.Was du da berechnest ist
1 + x^k/k!
Und dafür brauchst du keine Schleife.
-
Der wert für den fehler mit dem ich in die Schleife gehe setzt sich ja aus der Differenz von exp1-exp2 zusammen. Aber ich sehe gerade, dass die Variable erst in der Schleife einen Wert bekommt.
Ja, ich weiß das die Werte addiert werden müssten.
Müsste ich sonst schreiben
exp2= exp2+f
-
pepe90 schrieb:
Müsste ich sonst schreiben
exp2= exp2+fJa.
Oder exp2 += f;
-
Vielen Danke. Jetzt läuft alles.
Jetzt kann ich mich and as verschönern machen
-
Überleg mal, wie sich das f in jedem Schleifendurchlauf verändert.
Und auch deine erste Reihe ist sehr aufwendig.
-
Die erste Reihe muss halt auch durch eine Summenfunktion berechnet werden. Hierbei fibdet ein vorzeichenwechsel statt. Da wir in dem Praktikum noch keine andere Möglichkeit kennengelernt haben, musste ich es so machen.
-
double reihe1 = 1.0, nenner = 1.0; for (i=1; i <= n; i++) /*Reihe1*/ { nenner *= -2. ; // nenner = nenner * -2.0 ; reihe1 = reihe1 + 1.0/ nenner; }
-
Ja cool. Danke. Das ist ja echt kürzer und einfacher
-
Sowas kannst du auch bei Reihe2 machen.
Überleg dir mal, wie sich das f bei jedem Durchlauf verändert.