Errechnung der Zahl Pi in Java

B

BoneCracker

Mitglied
Hi,
ich habe mich heute mal dran gesetzt und ein paar Methoden geschrieben, mit welchen man in Java die Zahl Pi errechnen kann. Ich weiß, dass es Math.PI gibt, aber das ist ja langweilig .. Very Happy

Hier mal das, was ich bisher gemacht habe:
Code:
 /*
 * Created on 12.02.2005
 */
package pi;

/**
 * @author Bone
 */
public final class Pi {
    private Pi() {} // Keine Instanz erlaubt
   
    /**
     * Eine Rechnung, welche von den alten Ägyptern
     * benutzt wurde.
     *
     * Pi =~ (16/9)²
     */
    public static double agypten_pi() {
        return (((double)16 / 9) * ((double)16 / 9));
    }
   
    /**
     * Eine Rechnung, welche im alten Babylon benutzt
     * wurde. Sie leitet sich aus einem 12-Eck her, welches
     * in einem Kreis ist.
     * @see http://magnet.atp.tuwien.ac.at/scholz/projects/fba/graf2.gif
     */
    public static double babylonien_pi() {
        // Grad Zahl in Radiant umwandeln
        double rad   = 2 * Math.PI / 360 * (30 / 2);
        double hoehe = Math.cos(rad);
        double seite = Math.sin(rad);
        return 12 * seite * hoehe;
    }
   
    /**
     * Antiphon (430 v. Chr) war der Meinung, dass man
     * Pi errechnen könnte, in dem man sich den Kreis
     * einfach als ein Vieleck mit "unendlich" Ecken
     * vorstellt.
     */
    public static double griechenland_pi(int dreieck_anzahl) {
        int anzahl   = dreieck_anzahl;
        double grad  = ((double)360 / anzahl / 2);
        // Grad -> Radiant
        double rad   = 2 * Math.PI / 360 * grad;
        double hoehe = Math.cos(rad);
        double seite = Math.sin(rad);
        return anzahl * seite * hoehe;
    }
   
    /**
     * Um 510 n.Chr. gab Aryabhatiya folgende Regel zur
     * Bestimmung von pi an: "Addiere 4 zu 100,
     * multipliziere mit 8, und addiere 62 000.
     * Das Resultat ist der ungefähre Wert des
     * Umfanges eines Kreises mit dem Durchmesser 20 000."
     */
    public static double indien_pi() {
        // sonst wird eine Ganzzahl zurückgegeben   
        double vier = 4;
        return ((vier + 100) * 8 + 62000) / 20000;
    }
   
    /**
     * @see http://magnet.atp.tuwien.ac.at/scholz/projects/fba/fba.html#sec_Leibniz
     */
    public static double leibniz_pi(int durchlauf) {
        double pi   = 1;
        double eins = 1;
        int nenner  = 1;
       
        for (int i = 1; i <= durchlauf; i++) {
            nenner = nenner + 2;
            if ((i % 2) == 1) { // ist die Zahl gerade?
                pi = pi - (eins/nenner);
            } else {
                pi = pi + (eins/nenner);
            }
        }
       
        return 4 * pi;
    }
   
    /**
     * @see http://magnet.atp.tuwien.ac.at/scholz/projects/fba/fba.html#sec_Wallis
     */
    public static double wallis_pi(int zahlen) {
        double pi   = 1;
        int zaehler = 0;
        int nenner  = 0;
       
        for (int i = 2; i < zahlen+1; i++) { // mit 2 Anfangen
            if ((i % 2) == 1) { // 0.5 er Zahl
                zaehler = new Double(((i/2)-0.5)*2).intValue()+1;
                nenner  = i;
            } else {
                zaehler = i;
                nenner  = new Double(((i/2)-0.5)*2).intValue();
            }
            pi = pi * zaehler/nenner;
        }
        return pi*2;
    }
   
    /**
     * WARNING: Die nenner und zaehler werden leicht gesprengt
     *  -> durchlauf darf maximal 31 sein
     * @see http://magnet.atp.tuwien.ac.at/scholz/projects/fba/fba.html#sec_Machin
     */
    public static double machin_pi(int durchlauf) {
        double pi      = 0.5;
        long hilfzahl2 = 1;
        long nenner2   = 1;
        long zaehler   = 1;
        long nenner    = 1;
        int hilfzahl   = 1;
        int y          = 0;
       
        for (int i = 1; i <= durchlauf; i++) {
            y       = 1;
            zaehler = 1;
            nenner  = 1;
            for (int a = 0; a < i; a++) {
                zaehler = zaehler * y;
                nenner  = nenner  * ++y;
                y++;
            }
            hilfzahl  = hilfzahl + 2;
            hilfzahl2 = 1;
            for (int z = 0; z < hilfzahl; z++) {
                hilfzahl2 = hilfzahl2 * 2;
            }
            nenner2 = hilfzahl * hilfzahl2;
            pi = pi + ((double)zaehler / nenner) * ((double)1 / nenner2);
        }
       
        return 6 * pi;
    }
   
    /**
     * @see http://magnet.atp.tuwien.ac.at/scholz/projects/fba/fba.html#sec_Euler
     */
    public static double euler_pi(int durchlauf) {
        // TODO: implementieren
        return -1;
    }
   
    /**
     * Yoshiaki Tamura und Tasumasa Kanada haben mit
     * folgendem die meisten Stellen bisher von Pi
     * berechnet.
     */
    public static double tamura_pi(int durchlauf) {
        double pi = 0;
        double a = 1;
        double x = 1;
        double b = 1 / Math.sqrt(2);
        double c = 1 / 4;
        double y = 0;
       
        for (int i = 0; i < durchlauf; i++) {
            y = a;
            a = (a + b) / 2;
            b = Math.sqrt(b * y);
            c = c - x * ((a - y) * (a - y));
            x = 2 * x;
        }
        // TODO: Fehler - es kommt immer etwa "-33.343" heraus
        return ((a + b) * (a + b)) / (4 * c);
    }
   
    /**
     * TODO: Herausfinden, wie dieser Berechnungsart heißt
     */
    public static double nenner_pi(int durchlauf) {
        double pi  = 0;
        for (int i = 1; i < durchlauf; i++) {
            pi = pi + ((double)1/(i*i));
        }
        return Math.sqrt(pi*6);
    }
   
    /**
     * TODO: Herausfinden, wie dieser Berechnungsart heißt
     */
    public static double nenner2_pi(int durchlauf) {
        double  pi  = 0;
        int  hilfz  = 2;
        long nenner = 1;
       
        for (int i = 0; i < durchlauf; i++) {
            nenner = hilfz * ++hilfz * ++hilfz;
            if ((i % 2) == 1) { // gerade Zahl?
                pi = pi - ((double)1 / nenner);
            } else {
                pi = pi + ((double)1 / nenner);
            }
        }
       
        return pi * 4 + 3;
    }
   
    /**
     * Eine Monte-Carlo Methode, mit welcher man
     * Pi "erschießen" kann.
     */
    public static double erschiesse_pi(int tropfenzahl) {
        double pi = 0;
        int innerhalb = 0;
        int gesamt = tropfenzahl;

        while (tropfenzahl > 0) { // generiere Tropfen und addiere je nach Zugehörigkeit
            double dotx = 2 * Math.random() - 1;
            double doty = 2 * Math.random() - 1;

            if (Math.sqrt(dotx*dotx + doty*doty) <= 1) {
                // Punkt liegt innerhalb des Kreises
                innerhalb++;
            } else {
                // Punkt liegt außerhalb des Kreises
            }

            tropfenzahl--;
        }

        pi = 4*(double)innerhalb/gesamt;
        return pi;
    }
}

Die Funktion tamura_pi() funktioniert leider noch nicht.

Fallen euch noch ein paar Ideen mehr ein, wie man Pi berechnen kann oder wisst ihr, wie man diese noch etwas optimieren könnte?

Die letze Methode ist ürigens nicht von mir... diese habe ich bei wikipedia gefunden.

Mfg
 
Hi,
Leno schrieb:
Hab mir jetzt nicht alles ganz genau durchgelesen aber zumindest überflogen. Aber ich glaube folgende Methode fehlt dir noch:

Du kannst Pi auch über folgenden Satz berechnen: Die Wahrscheinlichkeit q, dass zwei natürliche Zahlen u, v keinen gemeinsamen Teiler haben ist 6/(Pi)^2.

Vielen Dank, ja, die fehlt noch. :)

Mfg
 
Hallo
vor ein paar Jahren hat mir mal ein Maschinenmonteur aus dem damaligen Ostblock folgende Berechnung für PI gezeigt: 355/113. KISS! (keep it simple and stupid!)
Gruss aus der Schweiz
Hawker
 
toll.. schon wieder ein nekromant..

auf bald
oenone

*trollt sich*
 

Ähnliche Themen

Prblem mit zeilenweises auslesen von Datei und schreiben nach mysql

JBidWatcher: Problem bei loading Auctions in Verbindung mit mySQL

Akonadi startet nicht mehr

NagiosGrapher 1.7.1 funktioniert nicht

CentOS 6.3 RADIUS - Keine Verbindung möglich

Zurück
Oben