Pi Nachkommastellen

Ghostman1711

Mitglied
Hallo, Ich habe ein Programm erstellt das mit Pi errechnet. Leider hat mein verwendetes Double nicht genug Nachkommastellen. Bitte um Lösung/Lösungsvorschlag

Java:
public class pi
{
  public static void main(String[] args) {
     double pi_zw = 0;
     double pi;
     int n;
    
    
     for (n=1;n <= 1000000000; n++) {
       pi_zw = pi_zw + 1 / Math.pow(n, 2);
       if ((n % 1000) == 0) {
         pi = Math.sqrt(pi_zw * 6);
         System.out.println(pi);
       }
     }
  }
}
 
Zuletzt bearbeitet von einem Moderator:

Ghostman1711

Mitglied
Ja Math.pi will ich nicht. Ich will Pi ja berrechnen und nicht nur anzeigen.

BigDecimal hab ich auch schon gedacht. Jedoch bekomm ich es nicht hin. Kann mir da jemand helfen??
 

JStein52

Top Contributor
Ja:

Code:
import java.math.BigDecimal;
import static java.math.BigDecimal.*;


/**
*
* @author Juergen
*/
public class MyPi {
    private static final BigDecimal TWO = new BigDecimal(2);
    private static final BigDecimal FOUR = new BigDecimal(4);
   
    public static void main(String[] args) {
        System.out.println(pi(100));
    }
   
    // Gauss-Legendre Algorithm
    public static BigDecimal pi(final int SCALE) {
        BigDecimal a = ONE;
        BigDecimal b = ONE.divide(sqrt(TWO, SCALE), SCALE, ROUND_HALF_UP);
        BigDecimal t = new BigDecimal(0.25);
        BigDecimal x = ONE;
        BigDecimal y;
       
        while (!a.equals(b)) {
            y = a;
            a = a.add(b).divide(TWO, SCALE, ROUND_HALF_UP);
            b = sqrt(b.multiply(y), SCALE);
            t = t.subtract(x.multiply(y.subtract(a).multiply(y.subtract(a))));
            x = x.multiply(TWO);
        }
       
        return a.add(b).multiply(a.add(b)).divide(t.multiply(FOUR), SCALE, ROUND_HALF_UP);
    }
   
    // the Babylonian square root method (Newton's method)
    public static BigDecimal sqrt(BigDecimal A, final int SCALE) {
        BigDecimal x0 = new BigDecimal("0");
        BigDecimal x1 = new BigDecimal(Math.sqrt(A.doubleValue()));
       
        while (!x0.equals(x1)) {
            x0 = x1;
            x1 = A.divide(x0, SCALE, ROUND_HALF_UP);
            x1 = x1.add(x0);
            x1 = x1.divide(TWO, SCALE, ROUND_HALF_UP);
        }
       
        return x1;
    }
}

Du kannst beim Aufruf die Anzahl der Dezimalstellen eingeben. Ist im Beispiel oben 100
 

JStein52

Top Contributor
Dass du eh immer nur eine Näherungslösung erhalten wirst, ist ja klar
Das stimmt. Wenn du oben den Algorithmus benutzt und pi z.B. auf 1000 Stellen berechnen lässt dann weicht er in den letzten 4 Stellen von dem korrekten Wert ab, das merkst du wenn du mal die letzten Stellen jeweils miteinander vergleichst. Lass dir mal 1000, 1004 und 1008 Stellen berechnen
 

Ghostman1711

Mitglied
Ja:

Code:
import java.math.BigDecimal;
import static java.math.BigDecimal.*;


/**
*
* @author Juergen
*/
public class MyPi {
    private static final BigDecimal TWO = new BigDecimal(2);
    private static final BigDecimal FOUR = new BigDecimal(4);
  
    public static void main(String[] args) {
        System.out.println(pi(100));
    }
  
    // Gauss-Legendre Algorithm
    public static BigDecimal pi(final int SCALE) {
        BigDecimal a = ONE;
        BigDecimal b = ONE.divide(sqrt(TWO, SCALE), SCALE, ROUND_HALF_UP);
        BigDecimal t = new BigDecimal(0.25);
        BigDecimal x = ONE;
        BigDecimal y;
      
        while (!a.equals(b)) {
            y = a;
            a = a.add(b).divide(TWO, SCALE, ROUND_HALF_UP);
            b = sqrt(b.multiply(y), SCALE);
            t = t.subtract(x.multiply(y.subtract(a).multiply(y.subtract(a))));
            x = x.multiply(TWO);
        }
      
        return a.add(b).multiply(a.add(b)).divide(t.multiply(FOUR), SCALE, ROUND_HALF_UP);
    }
  
    // the Babylonian square root method (Newton's method)
    public static BigDecimal sqrt(BigDecimal A, final int SCALE) {
        BigDecimal x0 = new BigDecimal("0");
        BigDecimal x1 = new BigDecimal(Math.sqrt(A.doubleValue()));
      
        while (!x0.equals(x1)) {
            x0 = x1;
            x1 = A.divide(x0, SCALE, ROUND_HALF_UP);
            x1 = x1.add(x0);
            x1 = x1.divide(TWO, SCALE, ROUND_HALF_UP);
        }
      
        return x1;
    }
}

Du kannst beim Aufruf die Anzahl der Dezimalstellen eingeben. Ist im Beispiel oben 100

Dieser Code geht leider nicht
 

InfectedBytes

Top Contributor
du kannst so viele Stellen berechnen wie du willst, bloß dauert das immer länger und länger und benötigt auch immer mehr und mehr speicher und irgendwann sind eben die Grenzen deines Rechners ausgeschöpft.

Außerdem brauchst irgendwann schon einen millionen € teuren supercomputer, ansonsten brauchste zig Jahre. Aktueller Rekord liegt glaube ich bei 13,3 billionen Nachkommastellen. Diese Berechnung hat auf dem Supercomputer über 200 Tage gebraucht
 

JStein52

Top Contributor
:):):) der SCALE-Parameter bei BigDecimal ist vom typ int und da ist der MAX_VALUE glaube ich bei ca. 2 Milliarden. Wenn ich mal so grob überschlage dass man mit eine schnellen Desktop für 1 Mio. Stellen ca. 1 Std. benötigt dann brauchst du für 1 Milliarde Stellen 1000 Std. (mal angenommen das geht linear was ich aber schon mal nicht glaube). Und dann müssen alle diese Ziffern ja auch gespeichert werden. Im Programm werden 7 BigDecimals angelegt 7 x 1 Milliarde Stellen, sagen wir mal 1 Byte pro Ziffer sind ca. 7 GByte (also rund ca. 10 GByte weil ja vielleicht auch noch implizit irgendwo noch ein bis zwei BigDecimals angelegt werden. Und damit sind wir jetzt bei 1 Milliarde Stellen.
 

JStein52

Top Contributor
Ja sag ich ja. Dann braucht er einen anderen Algorithmus. Was aber nichts prinzipielles an der Laufzeit ändert, höchstens beim Speicherverbrauch. Es gibt nämlich auch Algos die jede Stelle unabhängig von den vorhergenden berechnen können.
 

Ghostman1711

Mitglied
Ich weiß, Ich hab einen Pc der Seit 3 Jahren durchläuft und der hat eh fast nix zutun. 5 TB Speicher usw. Weiß jemand wie ich an so einen Algosrhymus komme??
 

JStein52

Top Contributor
Das ist aber eine hochriskante Sache. Wenn man sowas implementiert und es ist ein Fehler drin der sich erst nach 2 Jahren rechnen auswirkt wirst du dich ärgern ! ;);)
 

Ähnliche Java Themen

Neue Themen


Oben