Berechnung der n-ten Wurzel mit Iterationsverfahren



  • Schau mal hier:
    http://www.matheboard.de/archive/16457/thread.html
    Ist zwar C++, aber in C wirds wohl nicht ganz so anders sein.

    Für deine "hoch" funktion:

    double hoch(double a, double b)
    {
      double i = 0;
      double result = 1;  // a^0 == 1
    
      for (i = 0; i < b; ++i)
        result = result * a;
    
      return result;
    }
    

    Ist aber in dem oberen link mit enthalten. Dein Problem sollte jetzt geklärt sein, oder?

    Gruß
    Manda



  • MandaJohn schrieb:

    Für deine "hoch" funktion:

    double hoch(double a, double b)
    {
      double i = 0;
      double result = 1;  // a^0 == 1
      
      for (i = 0; i < b; ++i)
        result = result * a;
    
      return result;
    }
    

    inner schleife immer draufmultiplizieren ist ja doof, mach's doch so:

    // nur ganzzahlige exponenten
    double my_pow (double x, unsigned int n)
    {
        double z;
        if (!n)
            return 1;
        if (n & 1)
            return x * my_pow(x, n-1);
        z = my_pow (x, n/2);
        return z*z;
    }
    

    frei nach: http://en.wikipedia.org/wiki/Exponentiation_by_squaring#Squaring_algorithm
    ^^ sind übrigens weniger rekursionen als du schleifendurchläufe hast *fg*
    🙂



  • also ich hab den code eingebunden aber da funktioniert immer noch nix, echt kein plan wie das gehen soll, würd mich echt um weitere (konkrete) hilfe freuen....hier der aktuelle code:

    #include <stdio.h> 
    #include <math.h> 
    #include <conio.h> 
    
    main () 
    {   int      n, a, potenz, i, zaehl=0; 
        float    x1=1, x2=0, absdiff=0, genau=0.00000001; 
    	double	 my_pow (double x, unsigned int n)
    
        printf("Wert für n: "); 
        scanf("%i", &n); 
        printf("Wert für a: "); 
        scanf("%i", &a); 
    
        while (absdiff>genau) 
            { 
                x2=1/n((n-1)*x1+(a/(x1
    				{ 
    				double z; 
    				if (!n) 
    					return 1; 
    				if (n & 1) 
    					return x * my_pow(x, n-1); 
    						z = my_pow (x, n/2); 
    					return z*z; 
    				}		
    			))); 
                absdiff=x1-x2; 
            } 
    
        printf("x1= %f", x1); 
        printf("zaehl= %f", zaehl); 
    }
    


  • Also sorry, dass ich hier weiternerven muss aber ich hab immer noch keine ahnung wie ich das programm schreiben muss, kann mir nicht BITTE jemand konkret helfen???



  • Du musst schon schreiben was nicht funktioniert.

    Kannst du das Prog. compilieren?

    Wenn nein: Poste die Fehlermeldungen.

    Wenn ja: Was wird berechnet. Evtl Testausgaben machen.



  • Follfosten schrieb:

    also ich hab den code eingebunden aber da funktioniert immer noch nix, echt kein plan wie das gehen soll, würd mich echt um weitere (konkrete) hilfe freuen....hier der aktuelle code:

    #include <stdio.h> 
    #include <math.h> 
    #include <conio.h> 
    
    main () 
    {   int      n, a, potenz, i, zaehl=0; 
        float    x1=1, x2=0, absdiff=0, genau=0.00000001; 
    	double	 my_pow (double x, unsigned int n)
    
        printf("Wert für n: "); 
        scanf("%i", &n); 
        printf("Wert für a: "); 
        scanf("%i", &a); 
    
        while (absdiff>genau) 
            { 
                x2=1/n((n-1)*x1+(a/(x1
    				{ 
    				double z; 
    				if (!n) 
    					return 1; 
    				if (n & 1) 
    					return x * my_pow(x, n-1); 
    						z = my_pow (x, n/2); 
    					return z*z; 
    				}		
    			))); 
                absdiff=x1-x2; 
            } 
    
        printf("x1= %f", x1); 
        printf("zaehl= %f", zaehl); 
    }
    

    ^^ das in der schleife sieht sehr seltsam aus. diese my_pow-funktion musste aufrufen und nicht da mit reinquetschen. das geht etwa so:

    ...
    // startwerte: x = 1, k = wurzelexponent, a = zahl aus der die k-te wurzel gezogen wird 
    rechne:
    double x2 = ((k-1)*my_pow(x,k)+a)/k/my_pow(x,k-1);  // eine näherung berechnen  
    if (fabs(x2-x) < 1e-8)  // ausreichend genau?
    {
       // fertig, ergebnis in x2        
    } 
    else  // nicht genau genug?
    {
       // nächste runde 
       x = x2;
       goto rechne;
    }
    ...
    

    🙂



  • Ich werd bekloppt, das sieht jetzt i-wie so aus aber mit den hinweisen kann ich so richtig auch nix anfangen

    #include <stdio.h> 
    #include <math.h> 
    #include <conio.h> 
    
    main () 
    {   int      n, a, potenz, i, zaehl=0; 
        float    x1=1, x2=0, absdiff=0, genau=0.00000001; 
    	double	 my_pow (double x, unsigned int n)
    
        printf("Wert für n: "); 
        scanf("%i", &n); 
        printf("Wert für a: "); 
        scanf("%i", &a); 
    
        while (absdiff>genau) 
            { 
    			double x2 = ((k-1)*my_pow(x,k)+a)/k/my_pow(x,k-1);     
    			if (fabs(x2-x) < 1e-8)   
    			{ 
    					// fertig, ergebnis in x2         
    			} 
    			else  // nicht genau genug? 
    			{ 
    				// nächste runde 
    				x = x2; 
    				goto rechne; 
    			}
    
    		} 
    
        printf("x1= %f", x1); 
        printf("zaehl= %f", zaehl); 
    }
    
    1>------ Erstellen gestartet: Projekt: p4_a1, Konfiguration: Debug Win32 ------
    1>Kompilieren...
    1>p4_a1.c
    1>c:\dokumente und einstellungen\willi.super-acer\desktop\c-testat\p4_a1.c(7) : warning C4305: 'Initialisierung': Verkürzung von 'double' in 'float'
    1>c:\dokumente und einstellungen\willi.super-acer\desktop\c-testat\p4_a1.c(10) : error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'printf'
    1>c:\dokumente und einstellungen\willi.super-acer\desktop\c-testat\p4_a1.c(17) : error C2065: 'k': nichtdeklarierter Bezeichner
    1>c:\dokumente und einstellungen\willi.super-acer\desktop\c-testat\p4_a1.c(17) : error C2065: 'x': nichtdeklarierter Bezeichner
    1>c:\dokumente und einstellungen\willi.super-acer\desktop\c-testat\p4_a1.c(25) : warning C4244: '=': Konvertierung von 'double' in 'int', möglicher Datenverlust
    1>Das Buildprotokoll wurde unter "file://c:\Dokumente und Einstellungen\Willi.SUPER-ACER\Desktop\C-Testat\p4_a1\p4_a1\Debug\BuildLog.htm" gespeichert.
    1>p4_a1 - 3 Fehler, 2 Warnung(en)
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
    


  • Follfosten schrieb:

    aber mit den hinweisen kann ich so richtig auch nix anfangen

    *schluck* du tappst ja völlig im dunklen. ich glaub, du solltest unbedingt mal ein c-tutorial durcharbeiten, sonst wird das nix. tut mir leid für diese direkte antwort, aber mir kommt's so vor, als wenn du von C noch keinen blassen schimmer hast.
    🙂



  • Das versuch ich ja die ganze Zeit auszudrücken, das Problem ist halt, dass ich auch viele andere Aufgaben durcharbeiten muss und Programmierungist bei mir nicht mehr als ein Nebenfach, dementsprechend wenig bekommt man beigebracht und Zeit um sich das selber beizubringen war im Moment noch nicht... ich wüsste halt nicht wie ich das bis morgen schaffen soll, von daher hoff ich hier einfach auf Hilfe und über Weihnachten hätt ich dann zeit für Tutorials.... Von daher nochma die Bitte nach nem konkreten Code!

    Danke



  • Follfosten schrieb:

    Von daher nochma die Bitte nach nem konkreten Code!

    es gibt hier sowas wie ein ungeschriebenes gesetz, dass keine komplettlösungen geliefert werden und so, sondern nur hilfe zur selbsthilfe angeboten wird. nach überzeugung der meisten forenuser schadet abschreiben und nix verstehen mehr als es hilft. daher mein tip: lass die aufgabe entweder sausen und mach dich später mal dran (wenn du programmieren kannst), oder stell gezielte fragen zur C-programmierung, um erstmal deine c-kenntnisse zu erweitern.
    🙂



  • Wie soll ich denn in so kurzer Zeit das Ganze verstehen?? wenn ich die Aufgabe nicht mache darf ich an der prüfung im nächsten jahr nicht teilnehemn und muss das semester wiederholen, ich finde nicht dass das eine option ist... Ist mir schon klar dass ich durch kopieren nicht unbedingt schlauer werde aber ich sehe keine andere Möglichkeit, sonst brauch ich den kurs gar nicht weitermachen - also ich kann das leider nicht nachvollziehen, warum es so schlimm ist mir zu helfen. ich beschäftige mich auch mit anderen fachgebieten und da helfe ich grundsetzlich in den entsprechenden foren



  • Follfosten schrieb:

    Wie soll ich denn in so kurzer Zeit das Ganze verstehen?? wenn ich die Aufgabe nicht mache darf ich an der prüfung im nächsten jahr nicht teilnehemn und muss das semester wiederholen, ich finde nicht dass das eine option ist...

    na dann los, du hast noch einige stunden. internet durchsuchen, 20 threads mit konkreten fragen hier und in anderen boards aufmachen (aber niemals die leiseste andeutung machen, dass du eine fertige musterlösung willst), im IRC gibts auch online-hilfe zu C, google nach: 'nth root algorithm filetype:c' (oder ähnliches), sollte auch was liefern usw. das müsste machbar sein.

    Follfosten schrieb:

    ich beschäftige mich auch mit anderen fachgebieten und da helfe ich grundsetzlich in den entsprechenden foren

    wird hier ja auch gemacht, nur nicht wenn wir merken, dass man uns als kostenlosen hausaufgaben-erledigungsservice misbrauchen will, um sich arbeit zu sparen oder weil man vorher nix gelernt hat.
    🙂



  • /*
    Zusammenfassung:
    Die 3.Wurzel aus einer Zahl a mit einen
    nährungsverfahren berechnen. Die Iteration
    abbrechen wenn |Xneu - Xalt| >= eps ist.
    Xneu = ist der errechnete Wert
    Xalt = der Wert in der Formel
    eps  = für die Genauigkeit
    Formel:
    Xneu = ( 1/3 (2Xalt + (a/X²alt)) )
    */
    #include <stdio.h>
    #include <math.h>
    
    int main(void)
    {
        double a                = 0;   
        double eps            = 0.00001;
        double xneu            = 1;
        double xalt            = 1;
        double erg[50];
        int i                    = 0;   
        int j                    = 0;   
    
        fflush(stdin);                                   
        printf("Geben Sie eine Zahl ein: ");
        scanf("%lf", &a);    //Zahl einlesen
        fflush(stdin);           
        printf("\nGenauigkeit, z.B. 0.00001: ");   
        //Wenn [ENTER] gedrückt wird, dann soll der Vordefinierte
        //Wert genommen werden. Wenn was eingegeben wird, dann bitte
        //den eingegebenen Wert zur Berechnung nehmen
        if(getchar() == '\n')
            eps = eps;
        else
            scanf("%lf", &eps);
    
        do
        {
            //Xalt auf Xneu setzen
            xalt = xneu;
            //Xneu berechnen
            xneu=( (1.0/3.0) * ( (2*xalt) + (a/(pow(xalt,2)) ) ) );
            //Xneu in Array speichern
            erg[i] = xneu;
            i++;
        }
        //Solange ausführen, bis absolutbetrag >= eps ist
        while( fabs(xneu - xalt) >= eps );
    
        i--;
        printf("\n\n");
        //das Erg ausgeben
        printf("Die 3. Wurzel aus N\x84herung: %lf \n", erg[i]);
        //Erg mit der Pow() Funktion ausgeben
        printf(" Berechnung mit der pow()-Funktion: %f \n", pow(a,(1.0/3.0)) );
        //Anzahl der Iterationsschritte ausgeben
        printf(" Es wurden %d Iterationen ben\x94tigt\n", i+1);
        //Iterationsschritte ausgeben (verlauf)
        printf(" Verlauf der Iteration:\n\n");
    
        for(j=0; j<=i; j++)
            printf("Iterationsschritt %d: %lf\n",j+1 ,erg[j]);
    
        printf("\n\n");
        return 0;
    }
    

    "Stack around the variable n was corrupted"

    heißt was?



  • Quatsch, das hier ist der Code:

    #include <stdio.h>
    #include <math.h>
    
    int main(void)
    {
        double a                = 0;   
        double eps            = 0.00000001;
        double xneu            = 1;
        double xalt            = 1;
        double erg[50];
    	int n					= 1;
        int i                    = 0;   
        int j                    = 0;   
    
        fflush(stdin);                                   
        printf("Wert aus dem Wurzel zu ziehen ist: ");
        scanf("%lf", &a);    //Zahl einlesen
    	fflush(stdin);                                   
        printf("Wert fuer n-te Wurzel: ");
        scanf("%lf", &n);    //Zahl einlesen
    
        if(getchar() == '\n')
            eps = eps;
        else
            scanf("%lf", &eps);
    
        do
        {
            //Xalt auf Xneu setzen
            xalt = xneu;
            //Xneu berechnen
            xneu=( (1.0/n) * ( (n-1)*xalt + (a/(pow(xalt,n)) ) ) );
            //Xneu in Array speichern
            erg[i] = xneu;
            i++;
        }
        //Solange ausführen, bis absolutbetrag >= eps ist
        while( fabs(xneu - xalt) >= eps );
    
        i--;
        printf("\n\n");
        //das Erg ausgeben
    
        for(j=0; j<=i; j++)
            printf("Iterationsschritt %d: %lf\n",j+1 ,erg[j]);
    
        printf("\n\n");
        return 0;
    }
    


  • if(getchar() == '\n')
            eps = eps;
    

    ? Was solln das werden ^^

    Und was passiert bei deinem Code, wenn du mehr als 50 Schritte brauchst? (i>=50)
    Dann schreibst du in nicht reservierte Bereiche.



  • Dann eher so?

    #include <stdio.h>
    #include <math.h>
    
    int main(void)
    {
        double a                = 0;   
        double eps            = 0.00000001;
        double xneu            = 1;
        double xalt            = 1;
        double erg[50];
    	int n					= 1;
        int i                    = 0;   
        int j                    = 0;   
    
        fflush(stdin);                                   
        printf("Wert aus dem Wurzel zu ziehen ist: ");
        scanf("%lf", &a);    //Zahl einlesen
    	fflush(stdin);                                   
        printf("Wert fuer n-te Wurzel: ");
        scanf("%lf", &n);    //Zahl einlesen
    
    	while( fabs(xneu - xalt) >= eps );
        {
            xalt = xneu;
            xneu=( (1.0/n) * ( (n-1)*xalt + (a/(pow(xalt,n)) ) ) );
            erg[i] = xneu;
            i++;
        }
    
        i--;
        printf("\n\n");
    }
    


  • ^^sieht doch immer besser aus. in zeile 22 ist ein semikolon zuviel und 'scanf("%lf", &n)' geht auch nicht, weil 'n' ein int ist, %lf aber für doubles da ist. aber probier mal so:

    int main(void)
    {
        double a;  
        double eps            = 0.00000001;
        double xneu;
        double xalt            = 1;
        int n;
    
        printf("Wert aus dem Wurzel zu ziehen ist: ");
        scanf("%lf", &a);    //Zahl einlesen
        printf("Wert fuer n-te Wurzel: ");
        scanf("%d", &n);    //Zahl einlesen
    
        for (;;)
        {
            xneu = (n*xalt - xalt + a/pow(xalt, n-1))/n;
            printf ("%f\n", xneu);
            if (fabs(xneu - xalt) < eps)
                break;
            xalt = xneu;
        }
    }
    

    🙂



  • Und was ist jetzt mit dem auszugebenden Ergebnis?



  • Follfosten schrieb:

    Und was ist jetzt mit dem auszugebenden Ergebnis?

    ^^das programm printet doch alle berechneten werte aus. der letzte in der liste ist das endergebnis. *cry*
    🙂



  • Bei mir kommt da nen Fehlerfenster:

    Debug Assertion Failed!

    Program: ...
    File: printf.c
    Line: 54

    Expression: (format != NULL)


Anmelden zum Antworten