Search code examples
c++crandomsegmentation-faultpi

Pi-calculator program gives different output each time it's run


This is a program to calculate the value of Pi using the fact that "The probability of any two integers being co-prime is 6/π2." This program compiled successfully but when I try to run it, it gives the error:

Segmentation fault (core dumped)

I tried to change the condition statement in for-loop to i < 9999. By doing this, the program gives an output which varies(when run each time) between 3.000000, 3.162278 and Segmentation fault (core dumped).

I want to calculate the value of π only by using the property mentioned above. Please help.

Also, help me choose a better function that generates random numbers and suggest me some code improvements. Thank you.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

int gcd(int a, int b)
{
    // Everything divides 0 
    if (a == 0 || b == 0)
       return 0;

    // base case
    if (a == b)
        return a;

    // a is greater
    if (a > b)
        return gcd(a-b, b);
    return gcd(a, b-a);
}

int main()
{
    srand(time(0));

    int numberOne = rand();
    int numberTwo = rand();
    int coprime = 0;

    for(int i = 0; i < 99999; i++)
    {
        numberOne = rand();
        numberTwo = rand();

        if(gcd(numberOne, numberTwo) == 1)
        {
            coprime++;
        }

    }

    // co-prime/99999 = 6 / pi^2
    double pi = 599994/coprime;
    pi = sqrt(pi);

    printf("%f\n", pi);

    return 0;
}

Solution

  • OP's gcd() recurses too deep and causes a stack overflow. @OldProgrammer

    Consider a replacement recursive function that is more efficient

    Use FP math when doing the division

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <math.h>
    
    unsigned gcdu(unsigned a, unsigned b) {
      return (b == 0) ? a : gcdu(b, a % b);
    }
    
    int main(void) {
      srand(time(0));
    
      int numberOne = rand();
      int numberTwo = rand();
      int coprime = 0;
    
      for (int i = 0; i < 99999; i++) {
        numberOne = rand();
        numberTwo = rand();
        if (gcdu(numberOne, numberTwo) == 1) {
          coprime++;
        }
      }
    
      // double pi = 599994 / coprime;
      double pi = 1.0*599994 / coprime;  //Insure FP division
      pi = sqrt(pi);
      printf("%f\n", pi);
      return 0;
    }
    

    Output

    3.142940