質問
になっているもC++です。しています計算の値piから無限のシリーズ
pi=4 - 4/3 + 4/5 – 4/7 + 4/9 -4/11+ ...
のプログラムは、印刷の概算値はpiの後の最初の1,000日本シリーズです。こちらは自分のコード:
#include <iostream>
using namespace std;
int main()
{
double pi=0.0;
int counter=1;
for (int i=1;;i+=2)//infinite loop, should "break" when pi=3.14159
{
double a=4.0;
double b=0.0;
b=a/static_cast<double>(i);
if(counter%2==0)
pi-=b;
else
pi+=b;
if(i%1000==0)//should print pi value after 1000 terms,but it doesn't
cout<<pi<<endl;
if(pi==3.14159)//this if statement doesn't work as well
break;
counter++;
}
return 0;
}
で統なく、エラーや警告は、空のコンソール画面が表示された後実行します。まremove線"if(i%1000==0)"となど、これは構文なのでしょうかは実行印字毎pi値を停止させることなく、第二のでなければいいます。お使いいただくことによってもいます。思想であろう簡単な論理エラーになります。
解決
さて、私%1000年になることはない= 0、あなたのカウンタi = 1から実行として、そしてそこで2の単位で、私は常に奇数であり、1000の倍数になることはありません。
それは、近似の下または上のいずれかより高い精度になるだろう -それが終了したことがない理由は、アルゴリズムが正確3.14157に収束しないということです。あなたは「いつ3.14157の与えられたデルタ内」と言うので、書きたい
if (fabs(pi - 3.14157) < 0.001)
break
または似たような、しかし、あなたはあなたが停止する前に手に入れたい「閉じる」ます。
のために他のヒント
、私は常に奇数であるので、私%1000が0になることはありません。
あなたは複数の問題があります:
A。あなたが奇数のみを反復しているので、私は1000%== 0が真になることはありません。
B。パイ== 3.14159:浮動小数点数が表現されている方法は、(あなたが別の質問では、ここでそれについて読むことができる)ので、あなただけのような二重の値を比較することはできません。それが動作するために、あなたは別の方法で値を比較する必要があります - 一つの方法は、互いからそれらを減算し、絶対的な結果が0.0000001未満であることを確認することです。
。- い浮動小数点精度の問題です。試
if(abs(pi - 3.14159) < 0.000005)
. i%1000
いたしませんで0i
常におかしい。
それはすべきではない。
if (counter%1000==0)
私は開始1およびその単位による2.そして私はいつも奇数びつけることはございませんの倍数1000、if(i%1000==0)います。
直接比較する浮動作しない、浮動小数精度の問題です。が必要となりますを比較することの差値があります。
PI = 4 - 4/3 + 5分の4〜7分の4 + 4/9 -4/11 + ...
一般化
PI =Σ<サブ> I = 0 サブ> ∞(-1) I 4 /(2 I +1)
私たちのそれぞれの項にクリーンなアプローチを提供します。
I '番目の用語は、次式で与えられます。double term = pow(-1,i%2) * 4 / (2*i+1);
ここで、 I = 0,1,2、...、N
だから、私たちのループはかなり単純なことができ、繰り返しのいくつかの番号を指定するN
int N=2000;
double pi=0;
for(int i=0; i<N; i++)
{
double term = pow(-1,i%2) * 4 / (2*(double)i+1);
pi += term;
cout << i << "\t" << pi <<endl;
}
あなたの元の質問には、「プログラムはこのシリーズの最初の1,000の用語のそれぞれの後にパイの近似値を印刷しなければならない」と述べました。これは3.14159に達しているかどうかを確認する必要性を意味するものではありませんので、私はここにこれを含めていません。 pow(-1,i%2)
コールはちょうど(遅い)if
文を避け、 I 。
、反復回数、パイの大きさと補正項の大きさ(-4/25と言う)との差の後に、それはdouble
の精度を超えて行くほど小さくなることに注意してくださいますので、それに対処するために高精度タイプが必要になります。
デフォルトの腹筋ではint型のためであるABSのマクロを使用しています。ダブルスでは、cmathライブラリを使用します。
#include <iostream>
#include <cmath>
int main()
{
double pi=0.0;
double a=4.0;
int i = 1;
for (i=1;;i+=2)
{
pi += (1 - 2 * ((i/2)%2)) * a/static_cast<double>(i);
if( std::abs(pi - 3.14159) < 0.000001 )
break;
if (i > 2000) //1k iterations
break;
}
std::cout<<pi<<std::endl;
return 0;
}
ここで修正されたコードです。私は、誰かが同様の問題を持っている場合、それは将来に役立つかもしれないと思っています。
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double pi=0.0;
int counter=1;
for (int i=1;;i+=2)
{
double a=4.0;
double b=0.0;
b=a/static_cast<double>(i);
if(counter%2==0)
pi-=b;
else
pi+=b;
if(counter%1000==0)
cout<<pi<<" "<<counter<<endl;
if (fabs(pi - 3.14159) < 0.000001)
break;
counter++;
}
cout<<pi;
return 0;
}
ここでは良い方です
class pi_1000
{
public:
double doLeibniz( int i ) // Leibniz famous formula for pi, source: Calculus II :)
{
return ( ( pow( -1, i ) ) * 4 ) / ( ( 2 * i ) + 1 );
}
void piCalc()
{
double pi = 4;
int i;
cout << "\npi calculated each iteration from 1 to 1000\n"; //wording was a bit confusing.
//I wasn't sure which one is the right one: 0-1000 or each 1000th.
for( i = 1; i < 1000; i++ )
{
pi = pi + doLeibniz( i );
cout << fixed << setprecision( 5 ) << pi << "\t" << i + 1 << "\n";
}
pi = 4;
cout << "\npi calculated each 1000th iteration from 1 to 20000\n";
for( i = 1; i < 21000; i++ )
{
pi = pi + doLeibniz( i );
if( ( ( i - 1 ) % 1000 ) == 0 )
cout << fixed << setprecision( 5 ) << pi << "\t" << i - 1 << "\n";
}
}