Eulersche zahl mit Hilfe Taylorreihe



  • Hey ich schreib morgen ne Klausur und ich komm hier einfahc net auf den richtigen Quellcode....

    e[x]=1+x^1/1! + x^2/2! + .......

    #include <stdio.h>

    double exppow(double x, double gen)
    {

    double a=1.;
    double c=1.;
    int d=1;
    double e=1.;

    while(d<=gen)
    {

    a=a*x;

    c=c*d;

    e=e+ (a/c) ;

    d++;

    }
    return e;
    }

    int main (void)
    {
    printf(" %g ", exppow(4,4000) );
    }



  • ex=1+x1/1! + x^2/2! + .......

    #include <stdio.h>

    double exppow(double x, double gen)
    {

    double a=1.;
    double c=1.;
    int d=1;
    double e=1.;

    while(e<=gen)
    {

    a=a*x;

    c=c*d;

    e=e+ (a/c) ;

    d++;

    }
    return e;
    }

    int main (void)
    {
    printf(" %g ", exppow(4,4000) );
    }



  • Ein bisschen wenig informationen.
    Was erwartest du, was passiert.

    Wozu ist der Parameter gen da?

    Und bitte die Code-Tags benutzen: Code markieren un dauf den C-Button unter dem 😡 klicken.



  • Die Aufgabe ist:

    Programmieren und testen Sie eine Funktion exppow(), die die Exponentialfunktion
    e^x durch ihre Potenzreihe annähert.
    Die Summation soll abgebrochen werden, wenn der Betrag des aktuellen
    Summanden kleiner als die Genauigkeit e (Wert << 1) wird, die der Funktion
    als Parameter übergeben wird. Der Funktionskopf soll sein:
    double exppow(double x, double genauigkeit)

    mit

    printf(" %g ", exppow(4,4000) );
    

    sollte eig als ergebnis 54,598 herauskommen... wobei ich das mit der genauigkeit nich so ganz versteh..

    #include <stdio.h>
    
    double exppow(double x, double gen)
    {
    
    	double a=1.;
    	double c=1.;
    	int d=1;
    	double e=1.;
    
    	while(e<=gen)
    	{
    
    		a=a*x;
    
    		c=c*d;
    
    		e=e+ (a/c) ;
    
    		d++;
    
    	}
    	return e;
    }
    
    int main (void)
    {
    	printf(" %g ", exppow(4,4000) );
    }
    


  • Die 4000 ist aber dein Interpretation.

    Mit der Genauigkeit ist die Differenz zwischen zwei Schleifendurchläufen gemeint
    Da wären Werte deutlich kleiner 1 angesagt.
    Hier mal ein Beispiel für exppow(4,0.001)

    d     Änderung      e
         1:           4      5.000
         2:           8     13.000
         3:     10.6667     23.667
         4:     10.6667     34.333
         5:     8.53333     42.867
         6:     5.68889     48.556
         7:     3.25079     51.806
         8:      1.6254     53.432
         9:    0.722399     54.154
        10:    0.288959     54.443
        11:    0.105076     54.548
        12:   0.0350254     54.583
        13:    0.010777     54.594
        14:  0.00307915     54.597
        15: 0.000821108     54.598 Hier ist die Änderung kleiner als gen
    

    Das Problem in deinem ersten Programm ist, das du 4000 Durchläufe hast. 4000! ist aber für ein double doch etwas heftig.
    Das Problem bei der zweiten Version ist, das e eigentlich nicht größer als 54,598 werden kann, du aber warten willst, bis es über 4000 ist.



  • ich glaub die prüfung in Zeile 12 ist nicht richtig, da der neue summand (a/c) auf die genauigkeit geprüft werden soll. das a ist die aktuelle x potenz und das c die aktuelle fakultätszahl und der quotient davon ist dann der neue summand.
    die prüfung müsste dann sowas wie

    while( gen <= abs(a/c) )
    

    sein.



  • Ah super mit einer gen von 40 funktioniert der spaß dann 🙂



  • aber bei deiner algemeinen variante kommt nur 1 raus..



  • pepe123 schrieb:

    Ah super mit einer gen von 40 funktioniert der spaß dann 🙂

    Das ist der falsche Ansatz.

    Dafür gibt es kaum Punkte.

    Es geht bei der Genauigkeit um die Nachkommastellen.
    Nicht um irgendein fiktiven Wert.

    pepe123 schrieb:

    aber bei deiner algemeinen variante kommt nur 1 raus..

    Dann gib mal Werte kleiner als 1 für gen an. 0.001 ist nicht schlecht.



  • brauch ich für

    abs(a/c)
    
    #include <math.h>
    

    wenn ja brauch ich ne lösung nur mit <stdio.h>...



  • Das abs brauchst du hier nicht, da du ja nur positive Werte addierst.

    e^x=1+x^1/1! + x^2/2! + ....... 
         ^       ^        ^   da
    

    Das a/c ist doch das x^k/k!
    Und wenn dieser Teil sehr klein wird, brauchst du ihn auch nicht mehr addieren.

    Es gibt auch Taylorreihen wo das Vorzeichen wechselt und dann brauchst du den Betrag.
    In C ist das abs nur für Integerwerte da. Für Fließkommezahlen gibt es fabs.
    Und dafür bräuchtest du math.h.


  • Mod

    pepe123 schrieb:

    brauch ich für

    abs(a/c)
    
    #include <math.h>
    

    Für fabs (abs ist aus stdlib.h, aber hier falsch): Ja.

    wenn ja brauch ich ne lösung nur mit <stdio.h>...

    Ich denke, du solltest wohl selber in der Lage sein, eine Funktion zu schreiben, die den Betrag einer Zahl zurückgeben kann.

    Übrigens könntest du deine Vorfaktoren auch ein bisschen cleverer handhaben. Momentan werden a und c sehr schnell sehr groß, was ungünstig sein kann. Du benutzt aber in der Rechnung immer nur a/c. Da reicht es auch, nur a/c zu speichern und sich zu überlegen, wie sich a/c in jedem Durchlauf ändert.

    edit: DirkB war wie immer schneller



  • include <math.h> is doch gestattet...
    Danke für die Hilfe!!!!!

    #include <stdio.h>
    #include <math.h>
    
    double exppow(double x, double gen)
    {
    
    	double a=1.;
    	double c=1.;
    	int d=1;
    	double e=1.;
    
    	while(gen<=fabs (a/c))
    	{
    
    		a=a*x;
    
    		c=c*d;
    
    		e=e+ (a/c) ;
    
    		d++;
    
    	}
    	return e;
    }
    
    int main (void)
    {
    	int n=4;
    	printf(" %g ", exppow(n,0.001) );
    }
    

    [code="c"]



  • pepe123 schrieb:

    include <math.h> is doch gestattet...

    Ist aber, wie schon gesagt, gar nicht nötig.

    Um nochmal den Tipp von SeppJ bezüglich der Vorfaktoren aufzugreifen:

    double exppow(double x, double gen)
    {
      int d=1;
      double e=1.;
      double de=1;
    
    // Hier fehlt noch die Überprüfung, ob die Paramter sinnvolle Werte enthalten
    
      do
      {
        de *= x/d ;  // Hier wird nur noch mit dem Unterschied zum Vorwert gerechnet
    // Dadurch werden die Einzelwerte nicht so riesig groß
    
        e+=de;
        d++;
    
      } while(de>gen);
    
      return e;
    }
    
    int main (void)
    {
      printf(" %g ", exppow(1,1e-99) );
    }
    


  • warum sind die differenzen nur positiv? input x kann doch auch negativ sein und dann sind es die differenzen auch.



  • Okay das is jetz mein entgültiger Quellcode:

    #include <stdio.h>
    
    double exppow(double x, double gen)
    {
    
    	double ep=1;
    	double rg=1;
    	int i=1;
    
    	while(rg>gen)
    	{
    		rg=rg*x/i++;
    		ep=ep+rg;
    
    	}
    	return ep;
    }
    
    int main (void)
    {
    	printf(" %g ", exppow(3.0,0.001) );
    }
    


  • Jetz hab ich von nem Kumpel den Quellcode für sinus(x) bekommen:

    Allerdings versteh ich nicht was das %.3f im printf soll und iwie kommt da auch was falsches raus...
    Vll könnt ihr mie da auch helfen ?! 🙂

    #include <stdio.h>
    #include <math.h>
    
    double sinpow(double x, double genauigkeit)
    {
    	double sinus=x;
    	double rg=x;
    	int i=2;
    
    	while( fabs(rg)>genauigkeit)
    	{
    
    		rg = rg * -x * x / i / ( i + 1 );
    		sinus = sinus + rg;
    		i += 2;
    
    	}
    	return sinus ;
    }
    
    int main (void)
    {
    	printf(" sin(x)=%.3f \n", sinpow(3.14,0.01) );
    }
    


  • StarCraftFeuerteufel schrieb:

    warum sind die differenzen nur positiv? input x kann doch auch negativ sein und dann sind es die differenzen auch.

    😮 🙄 schäm



  • pepe123 schrieb:

    Allerdings versteh ich nicht was das %.3f im printf soll und

    Gibt dir die Zahl mit 3 Nachkommastellen aus.
    Siehe: http://www.cplusplus.com/reference/cstdio/printf/



  • Das programm müsste also jetz sin(3.14) berechenen.
    mein taschenrechner wirft da 0,054 aus aber das programm 0,001...


Log in to reply