PI computation (C)


We are using this series:

π²/6 = 1/1² + 1/2² + 1/3² + 1/4² + 1/5² + 1/6² + 1/7² + 1/8² + ...

piComputation.c

#include <stdio.h>             /* Header file for standard I/O library */
#include <math.h>                      /* Header file for math library */

int main(void)
{
    long i;
    double sum, current, pi;
    i = 1;                              /* Denominator of current term */
    sum = 0.0;                                           /* So far sum */
    do {
        current = 1/(((double) i)*((double) i));       /* Current term */
        sum = sum+current;                  /* Add current term to sum */
        i++;                                          /* Next term now */
    } while (current > 1.0e-15); /* Stop if current term is very small */
    pi = sqrt(6*sum);                   /* Compute approximation of pi */
    printf("Summed %8ld terms, pi is %10.8f\n", i-1, pi);
    return 0;
}

This code is part of the ip course of DIT.

Numerical Analysis

I calculated the absolute error and the absolute relative error of that approach. I calculated the absolute error of that(where x’ is the machine number)
x’ = 3.141592645

x= 3.141592653 (actual value)

|ε| = |x – x’| = 0.000000008 = 0.08 * 10^(-7) < 0.5*10^(-7)
which tell us that the machine value is going to be accurate at 7 decimal digits at the most.Here it is exact 7 digits.

Then I calculated the absolute relative error

|ρ| = |ε| / x = 0,025464790899483937645941521750815 * 10^(-7) =
0,025464790899483937645941521750815 * 10^(-9) < 5 * 10^(-9)
which says that at the most nine significant digits are going to be accurate. Here 8 digits are accurate.

One could also use Maching’s formula. A multi-threaded taylor series would look like this

#include <iostream>
#include <thread>
#include <cmath>

int main(void)
{
  double pi = 0;
  double piArray[4] =
  { 0.0 };

  try
  {
    std::thread first([&]()
    {
      std::cout << "In thread 1" << std::endl;
      for (double i = 1.0; i <= 10000000000.0; i += 1.0)
      {
        piArray[0] += 1.0 / (i * i);
      }
    });

    std::thread second([&]()
    {
      std::cout << "In thread 2" << std::endl;
      for (double i = 10000000001.0; i <= 20000000000.0; i += 1.0)
      {
        piArray[1] += 1.0 / (i * i);
      }
    });

    std::thread third([&]()
    {
      std::cout << "In thread 3" << std::endl;
      for (double i = 20000000001.0; i <= 30000000000.0; i += 1.0)
      {
        piArray[2] += 1.0 / (i * i);
      }
    });

    std::thread fourth([&]()
    {
      std::cout << "In thread 4" << std::endl;
      for (double i = 30000000001.0; i <= 40000000000.0; i += 1.0)
      {
        piArray[3] += 1.0 / (i * i);
      }
    });

    first.join();
    second.join();
    third.join();
    fourth.join();

    pi = piArray[0] + piArray[1] + piArray[2] + piArray[3];

    std::cout.precision(15);
    pi = sqrt(pi * 6.0);
    std::cout << "Pi: " << pi << std::endl;
  }
  catch (std::exception& ex)
  {
    std::cerr << "Exception: " << ex.what() << std::endl;
  }
  return 0;
}

This code is developed from Elkvis, from C board and he comments that: “it’s explicitly 4 threads, but could easily be modified to use any number of threads, or even detect the number of cores on the machine by using std::thread::hardware_concurrency().”

Have questions about this code? Comments? Did you find a bug? Let me know!😀
Page created by G. (George) Samaras (DIT)

One thought on “PI computation (C)

  1. Pingback: Help with calculating pi (beginner)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s