n-te Wurzel aus x ziehen



  • _-- schrieb:

    volkard schrieb:

    while (fabs(differenz) <= epsilon);
    

    sollte man nicht lieber differenz = temp - x; machen und dann das fabs() weglassen?

    Nö, du weißt ja nicht, welches kleiner ist.

    Aber man sollte die Bedingung negieren 😉



  • _-- schrieb:

    könnte man statt hoch(x, n-1) nicht einfach x nehmen?

    uups... hätte den text lieber bis zum verallgemeinerungsteil lesen sollen 🤡



  • was ich vergessen hab zu sagen. Es sollen keine anderen Bibliotheken verwendet werden. Also alles selber coden.



  • hab meinen code mal bissl geändert.
    die 3. wurzel aus 8 rechnet er zumindest richtig. aber bei anderen wurzeln kommen irgendwie komische ergebnisse raus. Und vorallem keine Kommazahlen.
    die verwendete formel ist eine formel die ein kumpel auf einem arbeitsblatt von seiner uni hatte:
    ai+1 = ai - ((ain - x)/ (n*ain-1))

    #include <stdio.h>
    const double epsilon = 0.0000005f;
    double temp, var, differenz;
    
    double hoch(double x, int n);
    
    double sqrtn(int x, int n){
      var = x;
      do{
        temp = x;
        x = x - (hoch(x, n)-var)/(n*hoch(x, n-1));
        differenz = x - temp;
        if(differenz < 0){
          differenz = -differenz;
        }
        printf("test\n");
      } while (differenz >= epsilon);
      return x;
    }
    
    double hoch(double x, int n){
      double temp;
      int i;
    
      temp = x;
      for(i = 1; i < n; i++){ 
      temp = temp * x;
      }
      return temp;
    }
    
    int main(void){
      printf("%lf\n" ,sqrtn(12208, 3));
      return 0;
    }
    


  • dein x ist immernoch int...



  • Riedelinho schrieb:

    die verwendete formel ist eine formel die ein kumpel auf einem arbeitsblatt von seiner uni hatte:
    ai+1 = ai - ((ain - x)/ (n*ain-1))

    das ist aber ne andere als die verallgemeinerungs formel von deinem ersten link 😕



  • Michael E. schrieb:

    _-- schrieb:

    volkard schrieb:

    while (fabs(differenz) <= epsilon);
    

    sollte man nicht lieber differenz = temp - x; machen und dann das fabs() weglassen?

    Nö, du weißt ja nicht, welches kleiner ist.

    Doch, beim Newton mit x0=x weiß man ja, was passiert.
    Im ersten Schritt hüpft xn evtl (wenn x<1) nach rechts und ab dann hüpft die Folge nach links ad infinitum. Es winkt eine do-Schleife recht freundlich. Falls sie jemals nicht nach links hüpft, war entweder n==1 und ein Sofort-Treffer ist passiert, oder die Rechengenauigkeit ist erschöpft und man ist bei der Maschinengenauigkeit angekommen. Man muß kein unbefriedigendes epsilon wählen oder den Zyklus abwarten.
    Also fabs weglassen und epsilon weglassen ist der gute Weg.
    Nur weiß der Prof das nicht. Ist das einer, dem man es erklären kann? Oder lieber stillschweigend machen, was er erwartet?



  • Also hab meinen Code nochmal verändert:

    #include <stdio.h>
    const double epsilon = 0.0000005f;
    double temp, var, differenz;
    
    double hoch(double x, int n);
    
    double sqrtn(double x, int n){
      var = x;
      do{
        temp = x;
        x = x - ((hoch(x, n)-var)/(n*hoch(x, n-1)));
        differenz = x - temp;
        if(differenz < 0){
          differenz = -differenz;
        }
        printf("test\n");
      } while (differenz >= epsilon);
      return x;
    }
    
    double hoch(double x, int n){
      double temp;
      int i;
    
      temp = x;
      for(i = 1; i < n; i++){ 
      temp = temp * x;
      }
      return temp;
    }
    
    int main(void){
      printf("%lf\n" ,sqrtn(1321, 3));
      return 0;
    }
    

    soweit ich es probiert habe müsste es stimmen...
    jann es jemand mal mit anderen werten versuchen?



  • Riedelinho schrieb:

    jann es jemand mal mit anderen werten versuchen?

    Hier ein Auto-Tester, der 10000 Wertepaare testet.

    #include <stdio.h>
    const double epsilon = 0.0000005f;
    double temp, var, differenz;
    
    double hoch(double x, int n);
    
    double sqrtn(double x, int n)
    {
        var = x;
        do
        {
            temp = x;
            x = x - ((hoch(x, n)-var)/(n*hoch(x, n-1)));
            differenz = x - temp;
            if(differenz < 0)
            {
                differenz = -differenz;
            }
        }
        while (differenz >= epsilon);
        return x;
    }
    
    double hoch(double x, int n)
    {
        double temp;
        int i;
    
        temp = x;
        for(i = 1; i < n; i++)
        {
            temp = temp * x;
        }
        return temp;
    }
    
    int main(void)
    {
        double basis1,exponent,potenz,basis2;
        for(basis1=1; basis1<=1000; basis1++)
        {
            for(exponent=1; exponent<=10; exponent++)
            {
                potenz=pow(basis1,exponent);
                basis2=sqrtn(potenz,exponent);
                if(fabs(basis2-basis1)>0.001)
                {
                    printf("Fehler! sqrtn(%f,%f)!=%f (richtig: %f)\n",potenz,exponent,basis2,basis1);
                }
            }
            printf("                    \r%f%% done...\r",(basis1*10+exponent)/100);
        }
        return 0;
    }
    

    Kein Fehler.



  • wärs nicht schön wenn auch basen zwischen .0,1. und negative getestet würden?


Anmelden zum Antworten