Created
August 25, 2020 03:06
-
-
Save john-hix/e447541a32192c6881268bf27e8ebc2f to your computer and use it in GitHub Desktop.
Approximate Pi
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// A program I made after Calculus II class because I was | |
// itching to apply the idea of using series to estimate certain | |
// mathematical constants. I use the Leibniz series knowing that | |
// there are better, faster-converging series out there. | |
// | |
// This program currently uses only built-in C++ data types rather | |
// than arbitrary precision numbers. As such, there are likely errors | |
// introduced to the calculation inherent to that data representation. | |
// | |
// Program output assumes Unicode for Greek/mathematical characters | |
#include <iostream> | |
#include <iomanip> | |
using namespace std; | |
/** | |
* Uses Leibniz Series to calculate Pi | |
* @param unsigned long int terms - Number of terms for series | |
* @return long double - Estimation of Pi | |
*/ | |
long double estimatePi(unsigned long int terms) { | |
unsigned long int i = 0; | |
long double sum = 0; | |
long double term = 0; | |
while (i < terms) { | |
// The denominator is a way of alternating between addition and | |
// subtration for each term in the series without using branching logic | |
// My assumption is that mod/multiply will be much faster even on CPUs with branch prediction. | |
sum += static_cast<int>(1 + (-2)*(i % 2)) / static_cast<long double>(2*i + 1); | |
i++; | |
} | |
return sum * 4; // Series gives pi/4, so multiply by 4 | |
} | |
/** | |
* Calculates error for the Leibniz Series given # of terms | |
* @param unsigned long int terms - Number of terms in the partial sum | |
* @return long double - Absolute value of the error | |
*/ | |
long double calcError(unsigned long int terms) { | |
return static_cast<long double>(4)/( 2*terms + 3); | |
} | |
// Harness to demonstrate that more iterations results in higher accuracy | |
int main() | |
{ | |
// Greet user | |
cout << "Estimate \u03C0 using the Leibniz series!\n\n"; | |
// Declare and initialize variables | |
unsigned long int terms = 1; // Number of terms in the series | |
long double error = 0.25; // Error in calculation | |
long double pi = 0.25; // Estimate of pi constant | |
// Priming prompt/read for terms | |
cout << "Enter # of terms (enter non-number to quit): "; | |
cin >> terms; | |
// Keep prompting and calculating until the user quits | |
while (cin) { | |
// Echo back terms entered | |
cout << "Calculating from " << terms << " terms . . . \n"; | |
// Run calculations | |
pi = estimatePi(terms); | |
error = calcError(terms); // Get error for calculation | |
// Display Pi estimate | |
cout << "\u03C0 \u2248" << ' ' | |
<< setprecision(10) << pi << endl; | |
// Display error calculation | |
cout << "error \u2248 \u00B1" << error << "\n\n"; | |
// Prompt for another term count | |
cout << "Enter # of terms (enter non-number to quit): "; | |
cin >> terms; | |
} | |
cout << "Goodbye!\n"; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment