Reputation: 85
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);
}
Upvotes: 0
Views: 2570
Reputation: 17505
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.
Upvotes: 0
Reputation: 268
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.
Upvotes: 1
Reputation: 27248
When your program is executed, rootxy
is less than area
, so 0 is returned.
Upvotes: 0
Reputation: 993263
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.
Upvotes: 0