Kapitel 12
Alle Codedateien dieses Kapitels herunterladen
12_3_SchweigenIstGold.cpp
/*
* Lösung für Übung 12.3 - Schweigen ist Gold
*
* Basiert auf 12_2_PiBerechnen.cpp, hinzugefügt wurde die Stelle, die mit
* #1 markiert ist
*
* Die eleganteste Lösung ist mit dem Modulo-Operator %. Sie können aber auch
* alternativ eine eigene Zählvariable hochzählen.
*/
#include <atomic>
#include <iomanip>
#include <iostream>
#include <string>
#include <thread>
int main()
{
std::cout << "Beenden mit der Entertaste" << std::endl;
// Möglichst viele Nachkommastellen ausgeben:
std::cout << std::setprecision(15);
// Zwei atomare Variablen zum Steuern des Threads
std::atomic<bool> active = true;
std::atomic<double> result = 0;
std::thread leibniz([&]() {
// Diese Implementierung nutzt die Leibnitz-Formel
double sign = 1; // Vorzeichen (+1 oder -1)
double pi = 0;
double denominator = 1;
while (active)
{
pi = pi + sign * (4 / denominator);
// Vorzeichen umdrehen
sign = -sign;
// Teiler um zwei erhöhen
denominator += 2;
// #1 Die Ausgabe auf gewisse Werte beschränken. Der Modulo-Operator %
// ist nicht für double Zahlen verfügbar, daher casten wir vorher in einen long long,
// der ebenfalls sehr große Zahlen beinhalten kann.
// Da die Variable denominator immer um zwei erhöht wird, testen wir auf 40 Millionen,
// um die Ausgabe wie erwünscht alle 20 Millionen Iterationen zu erhalten.
// Da denominator immer ungerade ist, testen wir auf die 1
if (static_cast<long long>(denominator) % 40000000 == 1)
{
std::cout << "\rStatus (" << denominator << "): "
<< pi;
}
}
// Ergebnis in der atomaren Variable speichern
result = pi;
});
// Im Haupt-Thread derweil auf die Entertaste warten
std::string tmp;
std::getline(std::cin, tmp);
// Enter wurde gedrückt. Nun den Thread herunterfahren
active = false;
leibniz.join();
std::cout << "\rEndresultat: " << result << std::endl;
return 0;
}