0

I wrote this to calculate pi by choosing a random point for x and y and checking to see if it is inside or outside of a unit circle, but i ran into a problem which i cant find out why. N is a number like 10, 100,1000 which is the number of points it trys to see is in the circle.

then if it is inside of the circle, it increments "inside" and then inside is divided by the number of N to get teh ratio, which should get closer to 3.1415.

Im not getting any values, and im not sure if that way i wrote it, if i will get a new random number for each loop of the while loop I am new to C, im trying to learn it after Java.

#include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> void initrand(void) { srand(time(0)); } float randfloat(void) { return rand()/(float)RAND_MAX; } int main(void) { int n = 10; float x; float y; float pi = 3.1415; float rootxy; initrand(); int z = 0; int inside = 0; x = randfloat(); y = randfloat(); float area = 0.25 * pi; float calculatedpi; rootxy = sqrt(pow(x,2) + (pow(y,2))); while (z < n){ if (rootxy > area) { inside++; z++; } else{ return 0; } calculatedpi = (inside/n); printf("%f", calculatedpi); } //printf("%f", calculatedpi); } 

Here is my revised loop when i debug it, it seems to work, all the way up to the calcutedpi part, it prints out 0.00000 and does not grab the values from inside the loop.

while (z < n){ x = randfloat(); y = randfloat(); rootxy = sqrt(pow(x,2) + (pow(y,2))); if (rootxy < area) { inside++; } else{ } z++; } calculatedpi = (inside/n); printf("%f", calculatedpi); } 
4
  • Please explain what problem you ran into. Commented Nov 6, 2011 at 18:15
  • i edited it, i forget about that. Commented Nov 6, 2011 at 18:16
  • 1
    You need to generate many pairs of numbers to use the method to "guess" PI: you only generate 1 such pair. Also having the variable float pi = 3.1415; in a program that tries to "guess" PI is kinda strange. Also, that value is somewhat bad. Try M_PI if you have a POSIX implementation (or 2 * asin(1)). Commented Nov 6, 2011 at 18:20
  • 1
    Oh! One other thing. Prefer to use double in the absence of a strong reason otherwise. Commented Nov 6, 2011 at 18:28

4 Answers 4

1

Here is an explanation of the Monte Carlo method for calculating pi:

http://www.chem.unl.edu/zeng/joy/mclab/mcintro.html

Try this:

snits@perelman:~/proj/c=>cat pi.c #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #define MAXSTR 256 int main(int argc, char **argv) { unsigned long int z = 0, n = 0, inside = 0; float x, y, rootxy, calculatedpi; char *str; size_t sz = MAXSTR; str = (char *)malloc(sz); if(!str){ fprintf(stderr,"malloc failed. exiting\n"); exit(EXIT_FAILURE); } printf("enter number of points to check: "); getline(&str,&sz,stdin); sscanf(str,"%lu",&n); srand(time(0)); while(z < n){ x = rand()/(float)RAND_MAX; y = rand()/(float)RAND_MAX; rootxy = sqrt(pow(x,2) + pow(y,2)); if (rootxy <= 1.0) inside++; z++; } /* pi = 4 * (number of hits)/(number of points checked) * for simple explanation of monte carlo method for pi * calculation see: * http://www.chem.unl.edu/zeng/joy/mclab/mcintro.html */ calculatedpi = 4*(float)inside/n; printf("%f\n",calculatedpi); return 0; } 

Here is a test run:

snits@perelman:~/proj/c=>gcc -Wall -o pi -lm -O2 pi.c snits@perelman:~/proj/c=>./pi enter number of points to check: 999999999 3.141638 

Edit: Note the check condition is rootxy <= 1.0, not rootxy < area. The radius of the unit cricle is 1.0, and if the point is within (or on) the circle rootxy will be less than or equal to 1.0.

Sign up to request clarification or add additional context in comments.

5 Comments

no need for sqrt: if the square root of a number is less than or equal to 1, the number itself is also less than or equal 1 ;)
@pmg not if you want every case, a random number could technically be 1. Square root of 1 is 1, and because you add the 2nd number,which could be anything higher than 0, would result in a number > 1. and mess up the results.
@BeagleBoy: the condition (sqrt(1.0000000 + 0.0000000001) <= 1) evaluates exactly the same as the condition (1.0000000 + 0.0000000001 <= 1). The values may be different (1.0000000000000000001 vs 1.000000001) though.
@pmg i just may be confused, but how can 1.0001 <= 1? Does the complier only see to a certain decimal?
What I said was if 1.0001 <= 1 then sqrt(1.0001) <= 1 (both are false); likewise (for a true condition) if 0.999 <= 1 then sqrt(0.999) <= 1, ...
0

That return 0; looks like it might prematurely exit your program. Is that what you wanted to do? The return statement in C works just like it does in Java; it exits the current function (breaking out of any enclosing loops) and returns the given value.

Also, your code currently chooses one set of random values for x and y, and doesn't change them within the loop. Wouldn't you want to choose a different x and y for each iteration?

If you're trying to calculate the value of π, what is the value pi doing in your code and why are you using it in the calculation?

It looks like there are some fundamental things wrong with your algorithm that are not related specifically to programming in C. Perhaps you could try to write this in Java first, and then convert that (working!) code to C.

2 Comments

Yes, for each iteration, i need new random numbers for x and y, would this be accomplished by putting x = randfloat(); and y = randfloat(); inside the loop?
That sounds like a good idea. What happens when you try that?
0

When your program is executed, rootxy is less than area, so 0 is returned.

Comments

0

Your problem is that you are doing integer arithmetic when calculating pi:

calculatedpi = (inside/n); 

In integer arithmetic, it will truncate the digits past the decimal point. Since inside<n, you will get 0. Try this:

calculatedpi = (1.0 * inside / n); 

which forces floating-point arithmetic.

Note that since this will always be less than 1, so you clearly are not calculating pi. In fact, you appear to be calculating pi/4. For something more accurate, try:

calculatedpi = (4.0 * inside / n); 

EDIT:

On second thought, your algorithm isn't quite right. Also, you're using an estimate of pi to estimate pi?

Try using the test if (rootxy < 1) to determine whether to increment inside. This will test whether your coordinate is inside the unit circle, which can be turned into a calculation of pi fairly easily. As is, I'm not sure that your algorithm calculates anything meaningful.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.