문제

또 다른 C ++ 운동을하고 있습니다. 무한 시리즈에서 PI의 값을 계산해야합니다.

PI = 4-4/3 + 4/5 - 4/7 + 4/9 -4/11 +. . .

이 시리즈의 첫 1,000 항 각각 후에 프로그램은 PI의 대략적인 값을 인쇄해야합니다. 내 코드는 다음과 같습니다.

#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;
}

오류와 경고없이 컴파일하지만 실행 후 빈 콘솔 창만 나타납니다. "if (i%1000 == 0)”라인을 제거하면 모든 PI 값이 실행되고 인쇄되는 것을 볼 수 있지만 중지되지 않으므로 두 번째 if 문도 작동하지 않습니다. 무엇을 해야할지 잘 모르겠습니다. 나는 그것이 아마도 간단한 논리적 오류라고 가정합니다.

도움이 되었습니까?

해결책

글쎄, 나는 당신의 카운터가 i = 1에서 실행되면 2의 증분으로 2의 증분으로 절대 = 0이되지 않습니다. 따라서 나는 항상 홀수이며 결코 1000의 배수가되지 않을 것입니다.

결코 끝나지 않는 이유는 알고리즘이 정확히 3.14157로 수렴하지 않기 때문입니다. 근사치 또는 근사치 이상의 정밀도가 될 것입니다. "주어진 델타 내에서 3.14157의 경우"라고 말하고 싶습니다.

if (fabs(pi - 3.14157) < 0.001)
  break

또는 비슷한 것, 그러나 "닫기"에 대해 멈추기 전에 가고 싶어합니다.

다른 팁

당신이 1에서 시작하고 2로 증가하기 때문에, 나는 항상 홀수이므로, 나는 % 1000은 결코 0이 아닙니다.

당신은 둘 이상의 문제가 있습니다.

A. I%1000 == 0은 홀수 만 반복하기 때문에 결코 사실이 아닙니다.

B. pi == 3.14159 : 부동 소수점 번호가 표시되기 때문에 이중 값을 비교할 수 없습니다 (다른 질문에서 여기에서 읽을 수 있음). 작동하려면 다른 방식으로 값을 비교해야합니다. 한 가지 방법은 서로를 빼고 절대 결과가 0.0000001보다 낮는지 확인하는 것입니다.

  1. 부동 소수점 정밀 문제가 있습니다. 노력하다 if(abs(pi - 3.14159) < 0.000005).
  2. i%1000 결코 0이 아닙니다 i 항상 이상합니다.

그렇지 않아야합니다.

if (counter%1000==0)
  1. 나는 1에서 시작한 다음 2로 증가합니다. 그러므로 나는 항상 홀수이며 결코 1000의 배수가되지 않기 때문에 (i % 1000 == 0)가 절대 지나치지 않는 이유입니다.

  2. 플로트 정밀 문제로 인해 플로트를 직접 비교하는 것은 작동하지 않습니다. 값의 차이가 충분히 가깝다는 것을 비교해야합니다.

pi = 4-4/3 + 4/5 - 4/7 + 4/9 -4/11 + ...

일반화

pi = σ=0 (-1) 4 / (2+1)

각 용어에 대한 더 깨끗한 접근 방식을 제공합니다. 그만큼 'Th 용어는 다음과 같이 제공됩니다.

double term = pow(-1,i%2) * 4 / (2*i+1);

어디 = 0,1,2, ..., 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 조에 따라 PI의 대략적인 값을 인쇄해야합니다"라고 언급했습니다. 이것은 3.14159에 도달했는지 여부를 확인할 필요가 없으므로 여기에 포함시키지 않았습니다. 그만큼 pow(-1,i%2) 전화는 피하는 것입니다 if 진술 (느리게)과 큰 합병증을 방지합니다. .

다수의 반복 후, PI의 크기와 수정 항의 크기 (-4/25)의 크기의 차이는 너무 작아서 double,이를 처리하려면 더 높은 정밀 유형이 필요합니다.

기본적으로 ABS는 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";
    }

}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top