Programm funktioniert nicht



  • Hallo,
    ich wollte ein Programm zum Berechnen von PI schreiben, das Problem ist, es geht nicht. Hier ist der Code:

    // Berechnung von PI
    
    #include <iostream>
    #include <cmath>
    
    using namespace std;
    
    int main()
    {
        // Definition wichtiger Werte
        double a = 1;
        double x = a;
        double b = 1 / sqrt (2);
        double c = 0.25;
        double pi;
    
        // Beginn des Algoithmus
        cout << "Wie oft soll die Schleife wiederholt werden?" << endl;
        int w;
        cin >> w;
        for ( int n=1 ; n<=w ; n++ ) 
        {
            // Nun der eigentliche Algorithmus
            double y = a;
            double a = (a+b)/2;
            double b = sqrt(b*y);
            double c = c-x*(pow(a-y,2));
            double x = 2*x;
            double pi = pow((a+b),2)/(4*c);
        } 
        cout << endl;
        cout << "Pi=" << pi << endl;
        system("PAUSE"); 
    }
    

    Ich komme nicht drauf, warum es nicht klappt.
    Es kommt immer raus: Pi=0
    Wobei mein Ergebnis theoretisch: Pi=3.1415926535897932384626433832795 sein müsste

    Gruß,
    Christoph



  • Du legst innerhalb der Schleife neue Variablen gleichen Namens an!

    P.S. double hat nur einen Präzision von 15-16 Stellen.
    Evtl. kann "long double" bei deinem System ein wenig mehr...



  • Also wäre das richtige Programm:

    // Berechnung von PI

    // Berechnung von PI
    
    #include <iostream>
    #include <cmath>
    
    using namespace std;
    
    int main()
    {
        // Definition wichtiger Werte
        long double a = 1;
        long double x = a;
        long double b = 1 / sqrt (2);
        long double c = 0.25;
        long double pi;
        long double y;
    
        // Beginn des Algoithmus
        cout << "Wie oft soll die Schleife wiederholt werden?" << endl;
        int w;
        cin >> w;
        for ( int n=1 ; n<=w ; n++ ) 
        {
            // Nun der eigentliche Algorithmus
            y = a;
            a = (a+b)/2;
            b = sqrt(b*y);
            c = c-x*(pow(a-y,2));
            x = 2*x;
            pi = pow((a+b),2)/(4*c);
        } 
        cout << endl;
        cout << "Pi=" << pi << endl;
        system("PAUSE"); 
    }
    

    Das dumme ist es kommt nur 3.14159 raus. Da müsste bei ner Schleife von 3 stehen
    3.141592653 😞



  • Beim Ausgeben wird wahrscheinlich gerundet.



  • knivil schrieb:

    Beim Ausgeben wird wahrscheinlich gerundet.

    nicht nur wahrscheinlich. Garantiert.

    @Christoph-C++ schau dir doch mal die Formatierungsoptionen für cout (bzw. allgemein für Ausgabestreams) an.



  • // Berechnung von PI
    
    #include <iostream>
    #include <cmath>
    #include <iomanip>
    
    using namespace std;
    
    int main()
    {
        // Definition wichtiger Werte
        long double a = 1;
        long double x = a;
        long double b = 1 / sqrt (2);
        long double c = 0.25;
        long double pi;
        long double y;
    
        // Beginn des Algoithmus
        cout << "Wie oft soll die Schleife wiederholt werden?" << endl;
        int w;
        cin >> w;
        for ( int n=1 ; n<=w ; n++ )
        {
            // Nun der eigentliche Algorithmus
            y = a;
            a = (a+b)/2;
            b = sqrt(b*y);
            c = c-x*(pow(a-y,2));
            x = 2*x;
            pi = pow((a+b),2)/(4*c);
        }
        cout << endl;
    
        cout << "Pi=" << std::setprecision(10)<<pi << endl;
        system("PAUSE");
    }
    


  • Sieht trotzdem nach C aus.



  • volkard schrieb:

    Sieht trotzdem nach C aus.

    Meinst du mit "C" "schlecht"?

    K&R-Style C kann es nicht sein, weil "int w" nicht am Anfang deklariert wird und in C99 wäre das schlechter Stil.



  • idiomatisch schrieb:

    volkard schrieb:

    Sieht trotzdem nach C aus.

    Meinst du mit "C" "schlecht"?

    Nee, ich meine, daß der Buchautor sich noch nicht in C++ reingefühlt hat.

    In dem Fall, daß er bis auf w erstmal alle Variablen am Funktionsanfang so unlokal definiert. Das Verwenden von endl paßt auch nicht. y ist so ganz und gar unlokal. Die Schleife von 1 bis <=w, hmm, das macht auch kein C-Könner. Das wird Christoph eingebaut haben, weshalb w auch besser platziert wurde.



  • Wie groß kann der Faktor von setprecision sein?



  • Also meinst du vielleicht Pascal oder sonst eine Sprache. In C wäre das ein while (w--) .

    @Christoph: Der Summand kann bis zu std::numeric_limits<long double>::digits gross sein (oder grösser, aber das hat dann keinen Einfluss mehr).



  • Christoph-C++ schrieb:

    Wie groß kann der Faktor von setprecision sein?

    Irgendwann machts doch eh kein Sinn mehr. http://en.cppreference.com/w/cpp/io/manip/setprecision



  • Was soll ich dann machen??



  • Dich darüber aufregen, es akzeptieren oder dir eine Bibliothek für variabel lange Zahlen suchen. (Ich empfehle Methode 2)



  • Noch lehrreicher ist es, sich eine eigene Klasse für Kommazahlen mit beliebiger Präzision zu schreiben.



  • Christoph-C++ schrieb:

    Was soll ich dann machen??

    • Du kannst noch eine Fehlerbehandlung bei der Eingabe einbauen,
    • Du kannst auch gucken, ob der <math.h>, bzw. <cmath>-Header Deines Systems PI schon implementiert hat.
    • Du kannst einen anderen Algorithmus wählen.
    • Du kannst die Schleife so umstellen, dass (wie in C und C++ üblich) von 0 angefangen wird und mit einfachem 'kleiner' ('<') gearbeitet wird.
    • Du kannst ziemlich viel mit der Ausgabe spielen (setprecision setw, fixed, scientfic) um das ganze aufzuhübschen.

    Alles dankbare Aufgaben.



  • Methode3 schrieb:

    Noch lehrreicher ist es, sich eine eigene Klasse für Kommazahlen mit beliebiger Präzision zu schreiben.

    Nein, nein, bitte nicht!



  • Methode3 schrieb:

    Noch lehrreicher ist es, sich eine eigene Klasse für Kommazahlen mit beliebiger Präzision zu schreiben.

    In welchen Situationen braucht man schon mehr als 10 Nachkommastellen?



  • ...



  • out schrieb:

    Methode3 schrieb:

    Noch lehrreicher ist es, sich eine eigene Klasse für Kommazahlen mit beliebiger Präzision zu schreiben.

    In welchen Situationen braucht man schon mehr als 10 Nachkommastellen?

    Stell Dir vor, Du hast einen Kreis mit dem Erdradius und willst den Umfang auf den Millimeter genau ausrechnen. 🤡


Anmelden zum Antworten