Search code examples
algorithmmathtrigonometrypiapproximation

calculating Pi different ways


I know two ways of calculating pi in code. Either

pi = 4.0 * atan(1.0)

or

pi = acos(-1.0)

What is the benefit of one vs. the other? I know there are some languages that have a built in pi representation, but this is not asking about them. Also, are there any other common ways of calculating pi as well as how they compare to others?


Solution

  • What is the benefit of one vs. the other?

    These functions were not designed only to approximate the value of π. In its case, I see no significant speed.

    As a matter of fact, I did a experiment on my system, where I see the same approximated value of pi with both functions, and the same speed, more or less.

    Georgioss-MacBook-Pro:~ gsamaras$ g++ -std=c++0x -Wall -O3 atan.cpp
    Georgioss-MacBook-Pro:~ gsamaras$ ./a.out 
    It took me on average 1.69e-13 seconds.
    3.14159265358979312
    Georgioss-MacBook-Pro:~ gsamaras$ g++ -std=c++0x -Wall -O3 acos.cpp
    Georgioss-MacBook-Pro:~ gsamaras$ ./a.out 
    It took me on average 1.7e-13 seconds.
    3.14159265358979312
    

    The code computes π in a loop, and adds the loop's counter to it, making sure that the compiler won't optimize that away (same value at every iteration):

    Georgioss-MacBook-Pro:~ gsamaras$ cat acos.cpp
    #include <iostream>
    #include <ctime>
    #include <ratio>
    #include <chrono>
    #include <cmath>
    #include <limits>
    
    #define ITER 1000000
    
    int main ()
    {
      using namespace std::chrono;
    
      high_resolution_clock::time_point t1 = high_resolution_clock::now();
    
      for(int i = 0; i < ITER; ++i)
      {
        auto pi = acos(-1.0) + i;
        pi += i + i;
      } 
      high_resolution_clock::time_point t2 = high_resolution_clock::now();
    
      duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
    
      std::cout << "It took me on average " << time_span.count()/(double)ITER << " seconds.";
      std::cout << std::endl;
      auto pi = acos(-1.0);
      std::cout.precision(std::numeric_limits< double >::max_digits10);
      std::cout << std::fixed << pi << std::endl;
    
      return 0;
    }
    

    based on my Time measurements (C++). The atan() code is the same, just the function changes.

    Also, are there any other common ways of calculating pi as well as how they compare to others?

    There are many other ways of approximating π and comparing them all is just too broad. For example, Plato has approximated π like this.