Bräuchte dringend ein Hilfestellung bei Informatik - Hausaufgaben - for Schleife - e-Funktion



  • Hallo,
    ich sitze schon seit mehreren Stunden an meiner Informatikhausaufgabe und bin mir eigentlich auch relativ sicher, dass ich diese zu 80% richtig gemacht habe.
    Am Ende bei der Berechnung der zweiten for-Schleife (eFkt.) ist allerding ein Fehler und ich weiß nicht welcher 👎

    Hier erstmal die Aufgabenstellung:

    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:
    e^x= Summe x^k/k! = 1+x+(1/2)x²+(1/(2*3)) *x³+... usw...

    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!

    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 10 und höchsten 20 ist. Sie müssen die Anzahl der Iterationsschritte aus der Eingabe-Zahl berechnen und dann entsprechend nach unten bzw. oben begrenzen.

    Nach Abschluss der Berechnung von Reihe 1 mit der vorstehend beschriebenen Anzahl von Iterationsschritten soll eine Programmausgabe erfolgen, die folgende Angaben, in dieser Reihenfolge, enthalten muss:

    1. Ergebniswert der Reihe aus der vorangegangenen Berechnung(Summenwert Reihe1)
    2. Anzahl der tatsächlich durchgeführten Iterationsschritte
    3. Idealer Ergebniswert der Reihe für unendlich viele Iterationsschritte (ist gegeben - bei mir 1.23370)

    Von dem Ergebniswert der Reihe 1 soll nun die Quadratwurzel gebildet werden. Benutzen Sie dazu die Mathematikfunktion sqrt() (math.h mit #include einfügen!). Das Ergebnis davon sei hier "X-Wert" genannt.
    Dieser Wert soll der x-Wert (Argumentwert) für die Berechnung der Exponentialfunktion werden. Bevor Sie die Reihe für die Exponentialfunktion berechnen, soll ex für den X-Wert durch die Funktion exp() aus der C Mathematik-Bibliothek ermittelt werden.
    Der Wert, den Sie durch den Aufruf der Funktion exp() erhalten soll mit einer Programmausgabe in der Form "exp(3.567) = 35.410" ausgeben werden (3.567 ist hier nur ein Beispiel für einen X- Wert).

    ➡ ➡ AB HIER WEIß ICH NICHT OB ICH RICHTIG PROGRAMMIERT HABE, DER TEIL DAVOR IST RICHTIG!! ⚠ ⚠

    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. Die Schleife soll die Reihe solange berechnen, bis ein vorgegebener Fehler unterschritten wird. Dabei wird als idealer Endwert der Iteration der Wert der Exponentialfunktion exp(x) definiert, mit x= X-Wert. Der Abbruchfehler soll ein Prozent von "exp(X-Wert)" sein. Das heißt, die Schleife soll so lange laufen, wie die Differenz "exp(X- Wert) – Summenwert" größer als "exp(X-Wert)/100" 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 (Differenz zum "idealen Endwert"), der aktuelle Summenwert der Reihe und die Anzahl der bisher ausgeführten Iterationen ausgegeben werden. Diese drei Ausgabe-Werte müssen alle in einer Ausgabezeile stehen. Jeder Schleifendurchlauf muss genau eine Ausgabezeile erzeugen.

    Als eingabewert die Nr. 999999 (als Beispielwert):

    das sind meine ausgabewerte:
    1.221798
    20
    1.233700
    exp(1.105)=3.020281
    m=1
    Reihe2=1.000000
    fehler=0.000000
    o=0.030203

    Programm:

    #include <stdio.h>
    #include <math.h>

    int main (void) {

    int n,m;
    double i, nenner=2.0, Reihe1, nenner2, nenner1,
    zaehler=1.0, xwert, exp1, idealw=1.233700,
    xhochk=1.0, k=1.0, fehler, Reihe2, o, p=1.0;

    scanf("%i",&n); /***Anzahl von 'n' Einlesen***/

    n=n%100;
    if (n<=10)
    {
    n=10;
    }
    else if (10<n, n<=20)
    {
    n=n;
    }
    else if (n>=20)
    {
    n=20;
    }

    Reihe1= 1.0;
    for(i=1;i<=n;i=i+1)
    {
    nenner1 = nenner * i+1 ;
    nenner2= nenner1*nenner1;
    Reihe1= Reihe1 + zaehler/nenner2;
    }
    printf("%lf\n%i\n%lf\n", Reihe1,n,idealw);

    xwert= sqrt(Reihe1); /**wurzel bilden**/
    exp1= exp(xwert);
    printf("exp(1.105)=%lf\n",exp1); /**e hoch wurzelzahl ausgabe**/

    o=exp1/100; /**1prozent von exp1**/
    Reihe2=1.0;

    for(m=1; fehler>o; m=m+1)
    {
    xhochk=xhochk*xwert;
    k=k*m; /** entspricht fakultät**/
    p=xhochk/k;
    Reihe2=Reihe2+p;
    fehler=exp1-Reihe2;
    }

    printf("m=%i\nReihe2=%lf\nfehler=%lf\n o=%lf",m, Reihe2,fehler,o);

    return 0;
    }

    Würde mich sehr über eine Antwort freuen! Danke im Vorraus 😉



  • MP1234 schrieb:

    ➡ ➡ AB HIER WEIß ICH NICHT OB ICH RICHTIG PROGRAMMIERT HABE, DER TEIL DAVOR IST RICHTIG!! ⚠ ⚠

    Das kannst du überhaupt nicht beurteilen.

    else if (10<n, n<=20)
    

    ist Schrott.

    Obendrein ist wird die Variable fehler uninitialisiert verwendet.



  • Danke erstmal für die Antwort.

    Hatte gedacht der 1. Teil ist richtig, da nach Test immer das richtige raus kam.
    Warum genau ist das Schrott? Ich wollte quasi sagen wenn die Zahl zwischen 10 und 20 ist, dann bleibt die Zahl bestehen.

    Was heißt Variable wird uninitialisiert verwendet?

    Sorry im programmieren bin ich absoluter Anfänger!



  • Das musst du mit && verknüpfen. Schalte am Besten auch Compilerwarnungen an. Das macht man mit -Wall, falls du gcc verwendest.



  • Wir verwenden einen Onlinecompiler von unserer Uni.

    Habe das nun mit && verknüpft -> else if (10<n && n<=20)

    heißt wenn man dazwischen ein komma setzt ist es ein Formfehler?

    Die 2. Reihe habe ich leider immer noch nicht hinbekommen.



  • MP1234 schrieb:

    heißt wenn man dazwischen ein komma setzt ist es ein Formfehler?

    Nein, willkommen in C wo extreme viele Sachen syntaktisch korrekt sind.
    Das ist der Kommaoperator. Der wertet den linken Ausdruck aus, dann den rechten, das Ergebnis ist dann der rechte.

    if (a < b, b < c)
    

    it quasi äquivalent zu

    a < b;
    if (b < c)
    


  • MP1234 schrieb:

    Habe das nun mit && verknüpft -> else if (10<n && n<=20)

    Lass den Teil doch einfach weg. Der Code n = n ist irgendwie sinnfrei.

    MP1234 schrieb:

    heißt wenn man dazwischen ein komma setzt ist es ein Formfehler?

    Es bedeutet etwas anderes.

    MP1234 schrieb:

    Die 2. Reihe habe ich leider immer noch nicht hinbekommen.

    Wann benutzt du fehler zum ersten mal in deinem Programm?
    Und welchen Wert hat es da?
    Und welche Auswirkung hat es da?



  • aber was wäre denn wenn n = 16 wäre, würde er dann automatisch die 16 übernehmen?

    das erste mal benutze ich fehler oben in der bennenung. Muss ich dort fehler = 1.0 einen wert geben?

    ich würde sagen es hat erst eine Auswertung sobald der erste durchgang gelaufen ist, oder?



  • Hallo,

    mir sind zunächst 2 Sachen aufgefallen.
    Soll in der ersten for-Schleife wirklich

    nenner1 = nenner * i+1; stehen?
    oder wäre
    nenner1 = nenner * (i+1); richtig?

    Zum Teil mit der Variable fehler:

    Ja, du solltest zukünftig deine Variablen mit einem Wert belegen, wenn du danach damit arbeiten willst.
    C gibt dieser Variable einen willkürlichen Speicherbereich in dem Werte stehen können, die du unter Umständen nicht gebrauchen kannst.
    D.h. es könnte in deiner Variable -10023 stehen oder auch 4012.

    Kleiner Tip:
    Benenn deine Variablen etwas sprechender, dann hast du (und wir habens) leichter dir zu helfen. 🙂



  • MP1234 schrieb:

    aber was wäre denn wenn n = 16 wäre, würde er dann automatisch die 16 übernehmen?

    Was soll dann sein?
    Überleg mal selber. bei n = n bekommt (das linke) n den Wert rechts vom = zugewiesen. Und das ist n.
    Welchen Wert hat n, wenn du die Zuweisung nicht machst?
    (Tipp: könnte n sein)

    MP1234 schrieb:

    das erste mal benutze ich fehler oben in der bennenung.

    Das erste mal benutzt du fehler in einer for-Schleife. Und zwar lesend.
    Zufällig ist der Wert von fehler gleich 0. (steht in deinem ersten Post)

    MP1234 schrieb:

    fehler=0.000000
    o=0.030203

    Die Schleife soll solange laufen, solange fehler > o ist.
    Hier ist aber fehler kleiner o und somit wird die Schleife nicht (mehr) ausgeführt.

    MP1234 schrieb:

    Muss ich dort fehler = 1.0 einen wert geben?

    Wenn 1.0 sinnvoll ist.

    MP1234 schrieb:

    ich würde sagen es hat erst eine Auswertung sobald der erste durchgang gelaufen ist, oder?

    Ja.

    Eine fußgesteuerte Schleife wäre hier auch möglich.


Anmelden zum Antworten