Quadratwurzel mit Heronverfahren


  • Mod

    Er will doch auch keine Verzweigung. Das klingt so, als wäre folgendes gesucht:

    double x0 = 1;
    double x1 = (x0 + a/x0) / 2;
    double x2 = ...;
    ...
    double x7 = (x6 + a/x6) / 2;
    cout << x7;
    

    Und was man bemerken soll? Vielleicht, dass man das auch arg viel kürzer und besser schreiben kann und der Prof einen mit dieser Aufgabe unnötig Arbeit macht.



  • 😮

    Will er wirklich eine so stumpfe Lösung haben?

    Warum wird erwähnt, dass man bei n = 8 abbrechen darf? Es muss also doch eine Zählvariable geben, wozu sonst der Hinweis?


  • Mod

    DocShoe schrieb:

    😮

    Will er wirklich eine so stumpfe Lösung haben?

    Weiß ich nicht, aber zumindest verstehe ich die Aufgabe so. Wobei ich die Aufgabe sehr unklar formuliert finde. Ich weiß nicht, was der didaktische Sinn dahinter sein sollte, aber ich wüsste genauso wenig, was der didaktische Sinn sein sollte, eine Iteration rekursiv zu schreiben.

    Warum wird erwähnt, dass man bei n = 8 abbrechen darf? Es muss also doch eine Zählvariable geben, wozu sonst der Hinweis?

    In der Formel in der Aufgabenstellung gibt es ein n.



  • SeppJ schrieb:

    Weiß ich nicht, aber zumindest verstehe ich die Aufgabe so. Wobei ich die Aufgabe sehr unklar formuliert finde. Ich weiß nicht, was der didaktische Sinn dahinter sein sollte, aber ich wüsste genauso wenig, was der didaktische Sinn sein sollte, eine Iteration rekursiv zu schreiben.

    Eine Iteration rekursiv zu schreiben, oder umgekehrt, kann schon dem Verständiss von Rekursionen dienen.

    Aber wenn wir hier zu dritt (mit TE zu viert) rum raten, was gewünscht sein soll, spricht das nicht für den Aufgabensteller.

    Wobei, wenn man die Aufgabe wörtlich nimmt, kommt SeppJs Lösung wohl hin...



  • DocShoe schrieb:

    😮

    Will er wirklich eine so stumpfe Lösung haben?

    Warum wird erwähnt, dass man bei n = 8 abbrechen darf? Es muss also doch eine Zählvariable geben, wozu sonst der Hinweis?

    ja er möchte wirklich solche Lösung haben , es ist leider der schlimmste Proff aus unseren Fachbereich sturrer alter Wirtschaftsinformatiker, bei dem ist sogar using namespace std; verboten. 😞
    Es ist auch keine Funktion erlaubt .
    Es passt woll von SteppJ der Vorschlag am Meisten 🙂



  • Hier ist mein Programm

    #include <iostream>
    
    using namespace std;
    
    int main() {
    
        double a;
    
        cout << "Bitte geben Sie eine Fließkommazahl ein: ";
        cin >> a;
        double x0 = 1; 
        double x1 = (x0 + a/x0) / 2;
        cout  << x1 << endl;
        double x2 = x1;
        double x3 = (x2 + a/x2) /2;
        cout << x3 << endl;
        double x4 = x3;
        double x5 = (x4 + a/x4) /2;
        cout << x5 <<endl;
        double x6 = x5;
        double x7 = (x6 + a/x6) /2;
        cout << x7 << endl;
    
        return 0;
    }
    

    ist das ok so? 🙂



  • Nein, das sind ja nur 4 Durchgänge.



  • SG1 schrieb:

    Nein, das sind ja nur 4 Durchgänge.

    Wenn ich acht Schritte mache bekomme ich das als Ausgabe:

    Bitte geben Sie eine Fließkommazahl ein: 9.7
    5.35
    3.58154
    3.14494
    3.11463
    3.11448
    3.11448
    3.11448
    3.11448



  • aus ästhetischen Gründen würde ich hier allerdings ein Makro einsetzen:

    #define F(x,y) double x = (y + a/y) /2
    

    und dann schreiben

    F(x1,x0);   //statt: double x1 = (x0 + a/x0) / 2;
    [...]
    F(x7,x6);   //statt: double x7 = (x6 + a/x6) /2;
    

    Man könnte auch noch die cout << ..-Zeile ins Makro packen.



  • zufallswert schrieb:

    aus ästhetischen Gründen würde ich hier allerdings ein Makro einsetzen:

    #define F(x,y) double x = (y + a/y) /2
    

    und dann schreiben

    F(x1,x0);   //statt: double x1 = (x0 + a/x0) / 2;
    [...]
    F(x7,x6);   //statt: double x7 = (x6 + a/x6) /2;
    

    Man könnte auch noch die cout << ..-Zeile ins Makro packen.

    ich glaube , dass mein proff damit nicht einverstanden würde(näheres lese vorherige Posts). Habe define nur in headern gesehen in main noch nie 🙄
    Aber trotzdem Danke für den Hinweis 😋



  • oder so:

    #include <iostream>
    using namespace std;
    double F(double a, double x){ return (x + a/x)/2; }
    int main() {
        double a;
        cout << "Bitte geben Sie eine Fließkommazahl ein: ";
        cin >> a;
        cout << F(a, F(a, F(a, F(a, F(a, F(a, F(a, F(a, a)))))))) << endl;
    }
    


  • oder besser:

    cout << F(a, F(a, F(a, F(a, F(a, F(a, F(a, F(a, 1)))))))) << endl;
    


  • ... oder so ....

    #include <iostream>
    using namespace std;
    
    double F(double a, double x){ return (x + a/x)/2; }
    double F2(double a, double x){ return F(a, F(a, x)); }
    double F4(double a, double x){ return F2(a, F2(a, x)); }
    double F8(double a, double x){ return F4(a, F4(a, x)); }
    
    int main() {
        double a;
        cout << "Bitte geben Sie eine Fließkommazahl ein: ";
        cin >> a;
        cout << F8(a, 1) << endl;
    }
    

  • Mod

    Proggerin schrieb:

    SG1 schrieb:

    Nein, das sind ja nur 4 Durchgänge.

    Wenn ich acht Schritte mache bekomme ich das als Ausgabe:

    Bitte geben Sie eine Fließkommazahl ein: 9.7
    5.35
    3.58154
    3.14494
    3.11463
    3.11448
    3.11448
    3.11448
    3.11448

    Deine Ausgabe hat nur 7 Stellen (ist die Standardeinstellung), der double wird aber genauer sein (so ca. 15 Stellen). Wenn du die precision erhöhst, sollte man das sehen können.



  • SeppJ schrieb:

    Proggerin schrieb:

    SG1 schrieb:

    Nein, das sind ja nur 4 Durchgänge.

    Wenn ich acht Schritte mache bekomme ich das als Ausgabe:

    Bitte geben Sie eine Fließkommazahl ein: 9.7
    5.35
    3.58154
    3.14494
    3.11463
    3.11448
    3.11448
    3.11448
    3.11448

    Deine Ausgabe hat nur 7 Stellen (ist die Standardeinstellung), der double wird aber genauer sein (so ca. 15 Stellen). Wenn du die precision erhöhst, sollte man das sehen können.

    PS: bin die Proggerin, habe mich registriert 🕶
    darf keine setter und getter benutzen . Geht es auch nicht mit float ?


  • Mod

    Du könntest theoretisch auch printf nutzen, wenn es unbedingt sein muss (Tu es nicht!), aber ich vermute ganz stark, dass du die Vorgabe missverstehst.



  • SeppJ schrieb:

    Du könntest theoretisch auch printf nutzen, wenn es unbedingt sein muss (Tu es nicht!), aber ich vermute ganz stark, dass du die Vorgabe missverstehst.

    Printf haben wir noch nie benutzt( ist wahrscheinlich verboten 🚫).
    Kannst du aus deiner Sicht erzählen wie du die Vorgaben siehst, bin leider ziemliche Anfängerin in Programmierung 🙄 .


  • Mod

    Ich weiß nicht, wie genau die Formulierung deiner Vorgaben lautet, aber mit "keien Getter/Setter" ist garantiert nicht gemeint, dass du nicht setprecision benutzen dürftest. Das ist was anderes.



  • in nächsten Aufgabe soll ich es genauso ,nur über Selektion und Iteration machen.
    Hier ist mein Versuch :

    #include <iostream>
    
    using namespace std;
    
    int main() {
    
        double a;
        double x, xn = 1; 
        cout<< "Bitte geben Sie eine Fliesskomazahl ein: ";
        cin >> a;
         if (a > 0){ 
          cout<< a << endl;
         }
    
     do { 
        x = xn; 
        xn = (x + a/x)/2; 
      } while (x != xn); 
      cout << x;
    
     return 0;
    }
    

    wie mache ich es das n bei 8 aufhört? Es fehlen noch Zwischenschritte bei der Ausgabe , wie gibt man die am besten aus? 🙄



  • Hi Helenchen,

    nimm entweder ne for-Schleife, oder lass ne Laufvariable mitlaufen, die Du vorher auf 0 setzt und dann bei jedem Durchlauf um 1 erhöhst. Die dann zusätzlich in der while-Bedingung abfragen.
    Den Text auf gleichheit würde ich bei Gleitkommazahlen nicht als einziges Abbruchkriterium nehmen. Kann zu leicht pasieren, dass die Schleife nie endet, weil das Ergebnis immer abwechselnd mal drunter und mal drüber liegt.
    Die Zwischenschritte nach dem jeweiligen Rechnen in der Schleife ausgeben.
    Eventuell den Startwert für xn auf ( a + 1 ) / 2 legen, dann könnte es schneller konvergieren.
    und natürlich die schleife in den if-Block legen, sonst wird bei negativem Wert doch gerechnet.

    #include <iostream>
    
    using namespace std;
    
    int main() 
    {
      double a;
      double x, xn = 1;
      cout<< "Bitte geben Sie eine Fliesskomazahl ein: ";
      cin >> a;
      if (a > 0)
      {
        cout<< a << endl;
        int n = 0;
        do 
        {
          x = xn;
          xn = (x + a/x)/2;
          cout<< n << " : " << x << endl;
          n++;
        } while ((x != xn)&&(n < 8));
        cout << x;
      }
      return 0;
    }
    

    oder so:

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      double a;
      double x, xn = 1;
      cout<< "Bitte geben Sie eine Fliesskomazahl ein: ";
      cin >> a;
      if (a > 0)
      {
        cout<< a << endl;
        for ( int n = 0; n < 8; n++ )
        {
          x = xn;
          xn = (x + a/x)/2;
          cout<< n << " : " << x << endl;
        }
        cout << x;
      }
      return 0;
    }
    

    Gruß Mümmel


Anmelden zum Antworten