In diesem Artikel verwenden wir die folgende Formel, um das Umfangsverhältnis in Java zu berechnen.
\frac{4}{\pi}=\sum_{n=0}^\infty \frac{(-1)^n(4n)!(1123+21460n)}{882^{2n+1}(4^nn!)^4}
Es ist der Beamte von Ramanujan (1887/12/22 --1920 / 4/26). Wenn ich es streng betrachte, frage ich mich, wie ich darauf gekommen bin und wie mir das wirklich ein Umfangsverhältnis gibt.
(Ich weiß nicht, um welche Formel es sich beim Austausch handelt.) Der folgende Austausch ist ebenfalls mysteriös.
Professor Hardy "Bitte sagen Sie mir, wie Sie auf diese Formel gekommen sind." Ramanujan "Bitte glauben Sie mir, Göttin Namagiri stand am Bett und lehrte mich."
Ich möchte es tatsächlich berechnen.
Grundsätzlich ist es ein Programm ohne Einfallsreichtum.
PamaPi.java
/**
*Berechnen Sie das Umfangsverhältnis.
*/
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
public class RamaPi {
/**
*Berechnen Sie den Boden(Verwenden Sie das vorherige Berechnungsergebnis erneut)。
*/
class Facto {
/**Letztes Argument*/
int n = 1;
/**Letzter Wert*/
BigInteger val = BigInteger.ONE;
BigInteger calc(final int arg) {
for ( ; n <= arg ; n++) {
val = val.multiply(BigInteger.valueOf(n));
}
return val;
}
}
/**Zur Multiplikationsberechnung 1*/
Facto workFacto1 = new Facto();
/**Zur Bodenberechnung 2*/
Facto workFacto2 = new Facto();
/**Konstante "882"*/
static final BigInteger VAL_882 = BigInteger.valueOf(882);
/**Konstante "4"*/
static final BigInteger VAL_4 = BigInteger.valueOf(4);
/**
*Berechnen Sie das offizielle Molekül von Ramanujan.
*/
BigInteger bunsi(final int n) {
final int sign = (n&1) == 0 ? 1 : -1;
final BigInteger a = workFacto1.calc(4 * n);
final BigInteger b = BigInteger.valueOf(sign * (1123 + 21460*n));
return a.multiply(b);
}
/**
*Berechnen Sie den offiziellen Nenner von Ramanujan.
*/
BigInteger bunbo(final int n) {
final BigInteger a = VAL_882.pow(2*n+1);
final BigInteger b = VAL_4.pow(n);
final BigInteger c = workFacto2.calc(n);
final BigInteger d = b.multiply(c).pow(4);
return a.multiply(d);
}
/**
*Berechnen Sie das Umfangsverhältnis aus der Ramanujan-Formel.
*/
void calc(final int digits) {
BigDecimal sum = BigDecimal.ZERO;
/**Anzahl der Ziffern, um das Hinzufügen zu stoppen (weniger als diese Anzahl von Ziffern kann nicht hinzugefügt werden)*/
final BigDecimal thr = BigDecimal.ONE.divide(BigDecimal.TEN.pow(digits));
/**Zeit, um mit der Berechnung zu beginnen*/
long t0 = System.nanoTime();
int iter = 0;
for ( ;; iter++ ) {
final BigDecimal bunbo = new BigDecimal(bunbo(iter));
final BigDecimal bunsi = new BigDecimal(bunsi(iter));
final BigDecimal adder = bunsi.divide(bunbo, digits, RoundingMode.HALF_EVEN);
if (adder.abs().compareTo(thr) < 0) {
break;
}
/*Schreibe die Summe mit dem Ergebnis der Addition um*/
sum = sum.add(adder);
/*Wenn die Anzahl der Stellen gering ist, wird der Konvergenzstatus angezeigt.*/
if (digits < 100) {
System.out.println( BigDecimal.valueOf(4).divide(sum, digits, RoundingMode.HALF_EVEN));
}
}
/**Zeitpunkt, zu dem die Berechnung abgeschlossen wurde*/
long t1 = System.nanoTime();
System.err.println("Anzahl der Wiederholungen: " + iter);
double elapsed = (t1 - t0) / ((double)1000 * 1000 * 1000);
System.err.println("Anzahl der benötigten Sekunden: " + String.format("%.6f", elapsed));
System.out.println(BigDecimal.valueOf(4).divide(sum, digits, RoundingMode.HALF_EVEN));
}
static public void main(String arg[]) {
int digits = Integer.parseInt(arg[0]);
new RamaPi().calc(digits);
}
}
Geben Sie die Anzahl der Stellen im Argument an. Möglicherweise liegt ein Fehler in den letzten Ziffern vor (der Fehler ist proportional zur "Anzahl der Wiederholungen").
java RamaPi 50
3.14158504007123775601068566340160284951024042742654
3.14159265359762201426827517920229156338712376594028
3.14159265358979322988767708881201158250039662639857
3.14159265358979323846265313702144396820307036308333
3.14159265358979323846264338326814215966511742779251
3.14159265358979323846264338327950289764449222972749
3.14159265358979323846264338327950288419715329619277
3.14159265358979323846264338327950288419716939939455
3.14159265358979323846264338327950288419716939937511
Anzahl der Wiederholungen: 9
Anzahl der benötigten Sekunden: 0.003002
3.14159265358979323846264338327950288419716939937511
Ich habe ein wenig in der Umgebung gemessen. Es dauert lange, aber denken Sie, dass Javas Mehrfachlängenberechnung schnell oder langsam ist?
Anzahl an Ziffern | Anzahl der Wiederholungen | Anzahl der benötigten Sekunden | Pers pro Zeit |
---|---|---|---|
10 | 2 | 0.001129 | 564.5 |
100 | 18 | 0.003077 | 170.9 |
1000 | 170 | 0.049033 | 288.4 |
10000 | 1698 | 4.237159 | 2495.3 |
20000 | 3395 | 19.83075 | 5841.1 |
40000 | 6790 | 118.651706 | 17474.4 |
Als ich versuchte, "Superπ" in derselben Umgebung zu verschieben, waren "8,38 Millionen Stellen" "152 Sekunden" (200-fache Anzahl von Stellen, was unterschiedlich ist).
Wenn Sie mehr Geschwindigkeit erreichen möchten, verwenden Sie etwas für Operationen mit mehrfacher Genauigkeit wie GMP (Die GNU-Bibliothek für mehrfache Präzisionsarithmetik) anstelle von Javas BigInteger / BigDecimal. Es ist definitiv besser.
Anfangs war es eine naive Implementierung von Bodenbelägen, aber es dauerte nur 20.000 Stellen und 113 Sekunden. (Zuerst habe ich es rekursiv geschrieben, aber es ist sofort übergelaufen: hashed :)
.java
/**
*Berechnen Sie den Boden.
*/
static final BigInteger facto(final int a) {
BigInteger work = BigInteger.ONE;
for (int i=2 ; i<=a ; i++) {
work = work.multiply(BigInteger.valueOf(i));
}
return work;
}
[Shrinivasa Ramanujan (Wikipedia)](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%A5%E3%83%AA%E3%83%8B%E3 % 83% B4% E3% 82% A1% E3% 83% BC% E3% 82% B5% E3% 83% BB% E3% 83% A9% E3% 83% 9E% E3% 83% 8C% E3% 82 % B8% E3% 83% A3% E3% 83% B3)
[Berechnung der willkürlichen Genauigkeit](https://ja.wikipedia.org/wiki/%E4%BB%BB%E6%84%8F%E7%B2%BE%E5%BA%A6%E6%BC%94% Einführungsartikel über E7% AE% 97) (Wikipedia)
Wenn Sie eine korrektere Berechnung mit mehreren Längen durchführen möchten, GMP
[Prominentes Programm zur Berechnung des Umfangsverhältnisses](http: // Umfangsverhältnis.jp/program/introduction.html)
Recommended Posts