Reputation: 137
i was wondering why in this program, "pi_estimated" wouldn't print out as a number with decimal places although the variable was declared as a "double". However, it prints out an integer.
double get_pi(double required_accuracy)
{
double pi_estimation=0.0;
int x,y;
double p=0.0,q=0.0,r=0.0;
int D=0;
for(int N=1;N<=1e2;N++)
{
x = rand()%100;
p = (x/50.0 - 1.0)/100.0;
y = rand()%100;
q = (y/50.0 - 1.0)/100.0;
r = p*p + q*q;
if((sqrt(r))<1.0)
{
D++;
pi_estimation = 4.0*(double (D/N));
}
if(double (4/(N+1)) < (required_accuracy*pi_estimation/100.0))
{
cout<<pi_estimation<<endl;
return (pi_estimation);
}
}
}
int main()
{
double pi_approx=0.0, a, actual_accuracy=0.0;
for(a=0.1;a>=1e-14;a/=10)
{
pi_approx = get_pi(a);
actual_accuracy = (fabs((pi_approx - M_PI)/(M_PI)))*100.0;
cout<<actual_accuracy<<endl;
}
}
Upvotes: 2
Views: 3528
Reputation: 234635
Since D and N are both integral types, D/N is performed in integer arithmetic; the cast to double happens too late as precision is lost prior to the cast.
One fix is to write 4.0 * D / N
. This will ensure that everything is calculated in floating point. (Since *
and /
have the same precedence, you don't need to write (double)
.)
Upvotes: 1
Reputation: 15872
The problem is here:
pi_estimation = 4.0*(double (D/N));
D
and N
are both integers, so D/N
is an integer that you are casting to a double and then multiplying by 4.0
.
You want to do this:
pi_estimation = 4.0 * (static_cast<double>(D) / N));
Upvotes: 1
Reputation: 59273
This line is the culprit:
pi_estimation = 4.0*(double (D/N));
Since D
and N
are both int
s, D/N
is an int
. Casting the int
to a double
cannot magically make decimals appear out of nowhere.
Here's the line, fixed:
pi_estimation = 4.0 * (((double) D) / N));
You could also multiply first, so you don't need so many parens:
pi_estimation = 4.0 * D / N;
D
is being multiplied by 4.0
, so it becomes a double
because double * int = double
. Then it's divided by N
. Since (x * y) / z
=== x * (y / z)
(associative property), the expressions are equivalent.
Upvotes: 6