Umfangsrate in Java

Einführung

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.

Programm

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);
	}
}

Ausführungsbeispiel

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

Über die benötigte Zeit

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.

Andere

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;
	}

Referenz

Recommended Posts

Umfangsrate in Java
Änderungen in Java 11
Janken in Java
FizzBuzz in Java
Lesen Sie JSON in Java
Machen Sie einen Blackjack mit Java
Einschränkungsprogrammierung in Java
Setzen Sie Java8 in Centos7
NVL-artiger Typ in Java
Verbinden Sie Arrays in Java
"Hallo Welt" in Java
Aufrufbare Schnittstelle in Java
Kommentare in der Java-Quelle
Azure funktioniert in Java
Formatieren Sie XML in Java
Einfache HTML-Spezialchars in Java
Hallo Welt in Java
Verwenden Sie OpenCV mit Java
WebApi-Memorandum mit Java
Typbestimmung in Java
Befehle in Java ausführen (Ping)
Verschiedene Threads in Java
Implementierung der Heap-Sortierung (in Java)
Zabbix API in Java
POST JSON in Java
Datumsmanipulation in Java 8
Was ist neu in Java 8?
Verwenden Sie PreparedStatement in Java
Was ist neu in Java 9,10,11
Parallele Ausführung in Java
Versuchen Sie es mit RocksDB mit Java
Vermeiden Sie den Fehler, den Yuma in Java gemacht hat
Holen Sie sich EXIF-Informationen in Java
Bearbeiten von ini in Java: ini4j
Java-Geschichte in dieser Welt
Versuchen Sie, JavaScript in Java aufzurufen
Probieren Sie den Funktionstyp in Java aus! ①
Ich habe ein Roulette in Java gemacht.
Implementierung der zweistufigen Authentifizierung in Java
Refactoring: Machen Sie Blackjack in Java
Themenanalyse (LDA) in Java
NEologd-Vorverarbeitung in Java neologdn-java
Ändern Sie die Java-Codierung in Windows
Java Stream API in 5 Minuten
Problem beim Finden von javax.annotation.Generated in Java 11 nicht
Lesen Sie die Standardeingabe in Java
Implementieren Sie die Standardauthentifizierung in Java
Suchen Sie eine Teilmenge in Java
[Java] KClass in Java herunterladen [Kotlin]
Erstellen Sie Azure-Funktionen in Java
Importieren Sie Excel-Daten mit Java
Implementieren Sie eine Kombination aus Mathematik in Java
JavaFX-Umgebungskonstruktion in Java 13
Java
Enum Strategiemuster in Java
2 Implementieren Sie eine einfache Syntaxanalyse in Java