2013-10-10 2 views
1

Мне было интересно, почему в этой программе «pi_estimated» не будет печататься как число с десятичными знаками, хотя переменная была объявлена ​​как «двойная». Тем не менее, он печатает целое число.«double» не печатает десятичные знаки

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; 
    } 
} 
+0

Потому что 'double (D/N)' не то, что вы думаете. Распечатайте его и убедитесь сами. –

ответ

6

Эта линия является виновником:

pi_estimation = 4.0*(double (D/N)); 

С D и N оба int с, D/N является int. Литье int в double не может волшебным образом сделать десятичные знаки из ниоткуда.

Вот, крепление:

pi_estimation = 4.0 * (((double) D)/N)); 

Вы также можете умножать первый, так что вам не нужно так много скобок:

pi_estimation = 4.0 * D/N; 

D в настоящее время, умноженное на 4.0, поэтому она становится a double, потому что double * int = double. Затем он делится на N. Начиная с (x * y)/z === x * (y/z) (ассоциативное свойство) выражения эквивалентны.

1

Проблема здесь:

pi_estimation = 4.0*(double (D/N)); 

D и N являются целыми числами, так D/N это целое число, которое вы бросаете к двойному, а затем умножением на 4.0.

Вы хотите сделать это:

pi_estimation = 4.0 * (static_cast<double>(D)/N)); 
1

Так как D и N является неотъемлемым типом, D/N выполняются в целочисленной арифметике; приведение к удвоению происходит слишком поздно, поскольку точность теряется до приведения в действие.

Одно исправление заключается в том, чтобы написать 4.0 * D/N. Это гарантирует, что все вычисляется в плавающей точке. (Так как * и / имеют одинаковый приоритет, вам не нужно писать (double).)

Смежные вопросы