The Term-inator: Pi edition The fourth project, continuing my C++ saga with terrible post names. :P


  An approximate value of pi can be calculated using the series given
  below:
  
  $$ \pi \approx 4 \left[ 1 - \dfrac{1}{3} + \dfrac{1}{5} - \dfrac{1}{7} +
 \dfrac{1}{9} - \cdots + \dfrac{\left( -1\right)^n}{2n + 1} \right] $$
  
  Write a C++ program to calculate the approximate value of pi using
  this series.  The program takes an input \$ n \$ that determines the
  number of terms in the approximation of the value of pi and outputs
  the approximation.  Include a loop that allows the user to repeat this
  calculation for new values \$ n \$ until the user says she or he wants
  to end the program.


Also, I am required to use a for loop at least once in my code.

pi.cpp:

/**
 * @file pi.cpp
 * @brief Calculates pi for the given number of terms
 * @author syb0rg
 * @date 10/3/14
 */

#include &lt;iostream&gt;
#include &lt;limits&gt;
#include &lt;cctype&gt;
#include &lt;cmath&gt;

/**
 * Makes sure data isn't malicious, and signals user to re-enter proper data if invalid
 */
void getSanitizedDouble(long double &amp;input)
{
    while (!(input = std::cin.peek()) &amp;&amp; input != '\n')
    {
        if (std::isalpha(input) || std::isspace(input)) std::cin.ignore(); // ignore alphabetic and space characters from input
    }
    while(!(std::cin &gt;&gt; input) || input &lt; 0)
    {
        std::cin.clear(); // clear the error flag that was set so that future I/O operations will work correctly
        std::cin.ignore(std::numeric_limits&lt;std::streamsize&gt;::max(), '\n'); // skips to the next newline
        std::cout &lt;&lt; "Invalid input.  Please enter a positive number: ";
    }
}

int main()
{
    long double num = 0.;
    char again = '\0';
    do
    {
        long double pi = 0.;

        // get input for height, re-read input if not a positive number
        std::cout &lt;&lt; "Enter the number of terms to approximate π: ";
        getSanitizedDouble(num);

        for(auto i = 0; i &lt; num; i++)
        {
            pi += std::pow(-1, i) / (2 * i + 1);
        }
        pi *= 4;

        std::fprintf(stdout, "Approximated value of π for %Lg terms: %Lg\n", num, pi);

        std::cout &lt;&lt; "Run the program again (y/N): ";  // signify n as default with capital letter
        std::cin.get();  // absorb newline character from previous input
        std::cin.get(again);
        again = std::tolower(again);
    } while (again == 'y');
}
Out parameters in C++

In C++, you should almost never use out parameters (variables taken by reference and used to return a value from a function), you can read this excellent article by Eric Niebler. There are few cases where out parameters can make sense:


When you want your return to be fast. And even then, return value optimization and move semantics may still be faster.
When you have several output values. For example, you want to assign a value to a function and return whether it succeeded:

bool assign(int from, int&amp; to)
{
    if (from != 0)
    {
        to = from;
        return true;
    }
    return false;
}


But even for this situation, there are better solutions such as boost:optional to return both a value and whether it succeeded or not. And if you need several error values, use exceptions. And if you need to actually return several values, you general want to pack them into a dedicated struct or a std::tuple.
Input-output parameters: sometimes, you want to take a parameter, read from it, and then write to it again. That is still a valid use case (but these are not strict out parameters anymore).


In your case, it seems that getSanitizedDouble could simply return the read long double instead of having an out parameter.

Type correctness

You could improve your type correctness:


That's also a naming issue: I don't expect a function named getSanaitzeDouble to return a long double, but to return a double.
The literal used in the expression long double pi = 0.; is incorrect: 0. is a double. The correct long double literal should be 0.0L. We could also use 0.0l, but the l suffix is really too close to 1 not to be dangerous.


Order your includes

Alphabetical order is something you should always use to order your headers (at least in a logical group of headers). That allows a faster search to check whether some headers has already been included:

#include &lt;cctype&gt;
#include &lt;cmath&gt;
#include &lt;iostream&gt;
#include &lt;limits&gt;