Как найти первое число пи, начинающееся с 3,14159 - PullRequest
2 голосов
/ 19 июня 2020

Чтобы определить, сколько терминов требуется для первого получения числа Пи, которое начинается с 3,14159, я написал следующую программу, которая вычисляет термины как (pi = 4 - 4/3 + 4/5 - 4/7 + ...).

Моя проблема в том, что в результате я достиг 146063 терминов, но когда я проверил, есть много писем, которые начинаются аналогично до этого.

//piEstimation.cpp
//estima mathematical pi and detrmin when 
//to get a value beganing with 3.14159

#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

int main(){
    //initialize vars
    double denominator{1.0};
    double pi{0};
    string piString;
    double desiredPi;    
    int terms;
    int firstDesiredTerm;

    //format output floating point numbers to show 10 digits after 
    // decimal poin
    cout << setprecision (10) <<fixed;

    for (terms = 1;  ; terms++){
        if(0 == terms % 2){ //if term is even
            pi -= 4/denominator;
        }
        else{ //if term is odd
            pi += 4/denominator;
        }

        // draw table
        cout << terms << "\t" << pi << endl;

        //determin first time the pi begains with 3.14159
        piString = to_string(pi).substr(0,7);
        if(piString == "3.14159"){
             firstDesiredTerm = terms;
             desiredPi = pi;
             break;
        }
        denominator += 2;
    }//end for

    cout << "The first time that pi value begans with 3.14159 "
        << "the number of terms are " << firstDesiredTerm << " and pi value is  "<< desiredPi <<endl;
}//end main

1 Ответ

2 голосов
/ 19 июня 2020

Число x начинается с 3,14159, если x >= 3.14159 && x < 3.1416. Нет необходимости использовать строки и сравнивать символы. to_string должен использовать какую-то операцию округления. Без строки алгоритм находит результат после 136121 шагов

#include <iostream>
#include <iomanip>

int main(){
    //initialize vars
    double denominator{1.0};
    double pi{0};
    double desiredPi;    
    int terms;
    int firstDesiredTerm;

    //format output floating point numbers to show 10 digits after 
    // decimal poin
    std::cout << std::setprecision (20) << std::fixed;

    for (terms = 1;  ; terms++){
        if(0 == terms % 2){ //if term is even
            pi -= 4/denominator;
        }
        else{ //if term is odd
            pi += 4/denominator;
        }

        // draw table
        std::cout << terms << "\t" << pi << std::endl;

        if(pi >= 3.14159 && pi < 3.1416){
             firstDesiredTerm = terms;
             desiredPi = pi;
             break;
        }
        denominator += 2;
    }//end for

    std::cout << "The first time that pi value begans with 3.14159 "
        << "the number of terms are " << firstDesiredTerm 
        << " and pi value is  "<< desiredPi << std::endl;
}

Вывод:

The first time that pi value begans with 3.14159 the number of terms are 136121 and pi value is  3.14159999999478589672

Здесь вы можете увидеть, как to_string округляет результат:

#include <iostream>
#include <iomanip>
#include <string>

int main(){
    std::cout << std::setprecision (20) << std::fixed;
    std::cout << std::to_string(3.14159999999478589672) << '\n';
}

Вывод:

3.141600

Вы можете прочитать на cppreference

std::string to_string( double value ); Преобразует значение с плавающей запятой в строку с тем же содержанием, что и std::sprintf(buf, "%f", value) будет производить для достаточно больших buf.

Вы можете прочитать на cppreference

f F Точность определяет точное количество цифр, которые должны появиться после символа десятичной точки. Точность по умолчанию - 6

Это означает, что std::to_string округляется после 6 цифр.

...