Skip to content

Instantly share code, notes, and snippets.

@john-hix
Created August 25, 2020 03:06
Show Gist options
  • Save john-hix/e447541a32192c6881268bf27e8ebc2f to your computer and use it in GitHub Desktop.
Save john-hix/e447541a32192c6881268bf27e8ebc2f to your computer and use it in GitHub Desktop.
Approximate Pi
// 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