Pi berechnen

  • Java

Es gibt 30 Antworten in diesem Thema. Der letzte Beitrag () ist von Jonas Jelonek.

    Pi berechnen

    Guten Tag

    Ich habe mir nach der Beschreibung auf dieser Seite den Chudnosky-Algorithmus geschrieben. Leider kommt bei mir als Ergebnis immer NaN. Kann mir vielleicht jemand sagen warum?

    Java-Quellcode

    1. public void calculatePi(double n) {
    2. double pi = 0.0;
    3. for (double k = 1.0; k <= n; k++) {
    4. pi += (Math.pow(-1.0, k) * factorial((int)(6.0 * k)) * ((545140134.0 * k) + 13591409.0)) / (factorial((int)(3.0 * k)) * Math.pow(factorial((int)k), 3.0) * Math.pow(640320.0, 3.0 * k + 1.5));
    5. }
    6. pi = 1.0/(12.0*pi);
    7. System.out.println(String.valueOf(pi));
    8. }
    9. public int factorial(int n) {
    10. int res = 1;
    11. for (int i = 2; i <= n; i++) {
    12. res *= i;
    13. }
    14. return res;
    15. }


    Vielen Dank im Voraus

    Jonas Jelonek

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Jonas Jelonek“ ()

    Eine korrekte Factorial-Funktion sieht so aus:

    Java-Quellcode

    1. int Factorial(int value)
    2. {
    3. int result = 1;
    4. for (int i = 2; i <= value; i++)
    5. result *= i;
    6. return result;
    7. }
    Beachte, dass die mathematische Definition von 0! = 1 ist.
    Factorial ist außerdem nur für Ganzzahlen definiert.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Artentus“ ()

    Artentus schrieb:

    Ganzzahlen
    Da bist Du allerdings mit dem Datentyp Integer unheimlich schnell am Anschlag. Long reicht da ggf. auch nicht.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ja, hatte da nen kleinen Denkfehler. Auf jeden Fall geht es jetzt teilweise, ich bekomme eine Zahl, die nicht wirklich was mit Pi gemeinsam hat, naemlich -1.6719416596966503E14. Woran kann es noch liegen, dass es nicht richtig funktioniert?
    Es funktioniert jetzt komplett. Ich musste in der For-Schleife im Algorithmus k am Anfang auf 0 setzen, ist eigentlich auch logisch und ich habe es in der Formal von der oben gegebenen Seite uebersehen.

    Vielen Dank fuer eure Hilfe

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Jonas Jelonek“ ()

    Leider muss ich euch nochmal um Hilfe bitten, undzwar geht es darum, dass ich zwar jetzt eine richtige Zahl bekomme, nur nicht festlegen kann, wie viel Stellen berechnet werden sollen, da der Parameter k nicht darauf reagiert und wenn k>11 dann kommt NaN.
    Woran kann es liegen.

    nafets3646 schrieb:

    als Ersatz verwenden?
    Da gibt es 2 Herangehensweisen.
    1. Du willst die exakte Zahlenfolge, da wäre BigInteger das richtige, wenn Du nur "einfach" eine iwie gerundete Zahl brauchst, wäre Double denkbar.
    Allerdings kann man auch komplexer rangehen (nicht Komplexe Zahl!) und die Mantisse in einem Double und den Exponenten in einem Integer oder Long abspeichern.
    -----

    Jonas Jelonek schrieb:

    wenn k>11 dann kommt NaN.
    Dann musst Du mal einen Haltepunkt reinsetzen und die Rechnung im Einzelschritt verfolgen. Nimm parallel dazu den Calc.exe.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich habe die ganze Rechnung nochmal ueberprueft, es hat sich kein Fehler ergeben. Das mit k>11=NaN lag daran, dass ich bei der factorial-Funktion int anstatt long genommen hab. Jedoch kann ich mit veraendern des Parameters k immernoch nichts machen, es kommt immer das gleiche Ergebnis.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Jonas Jelonek“ ()

    Naja, aber wenn ich in meinem Programm sage, ich will 3 Nachkommastellen, spuckt er mir 16 aus. Das kann ich auch mit n=2;4;5;6;7 usw. machen, immer kommen 16 Nachkommastellen, ab n=22 ist Schluss, das liegt aber am gewaehlten Datentyp in der factorial-Funktion und ist jetzt nicht so relevant fuer das eigentliche Problem. Ich haette da jetzt eher gedacht, der PC rechnet mit zu vielen gueltigen Stellen.
    Eben weil Double vergleichsweise sehr ungenau ist. Ich weiß nicht, wie die Taschenrechner zahlen darstellen, aber da treten eigentlich so gut wie keine Rundungsfehler auf und auch Sachen wie Pow funktionieren da viel besser. Du musst auch sehen, am Anfang sind es am PC vermutlich auch nur minimale Abweichungen, aber je öfter du es durchführst, desto stärker werden die Abweichungen.
    Du könntest z.B. mal nen Blick auf meinen Rational werfen, der wird jede Rechenoperation garantiert abweichungsfrei durchführen (sofern das Ergebnis nicht reell ist, das kann aber nur bei den auskommentierten Funktionen passieren). Die Berechnungen werden damit aber wesentlich langsamer, das muss dir klar sein.