高精度计算PI值

    • 题目描述
      • 描述
      • 输入
      • 输出
      • 样例
    • 分析思路
    • 代码

题目描述

描述

限制使用双向链表作存储结构,请根据用户输入的一个整数(该整数表示精确到小数点后的位数,可能要求精确到小数点后500位),高精度计算PI值。可以利用反三角函数幂级展开式来进行计算:

输入

输入的一个正整数n

输出

输出PI的值,精确到小数点后n位,最后输出一个回车。

样例

输入样例

5

输出样例

3.14159

分析思路

这是一个数据结构作业,要求使用双向链表作为储存结构。题目难度不大。提示用反三角函数的幂级展开式来进行计算。
在展开式中,取 x=12 x = 1 2 arcsinx=π6 a r c s i n x = π 6 .既有:
π6=mnRn π 6 = ∑ n m R n , Rn+1=(2n1)22n(2n+1)Rn R n + 1 = ( 2 n − 1 ) 2 2 n ( 2 n + 1 ) R n .
利用该式求出展开式中各项的值,便能算出要求精度的 π π 值。
具体实现中一个节点保存一位数。主要的操作有加、乘、除。通过模拟手算的方法实现。

代码

#include 
#include 
#include 
using namespace std;

struct Node{
    char elem;
    Node *nex, *pre;
    Node(int elem = 0, Node *nex = 0, Node *pre = 0):elem(elem), nex(nex), pre(pre){}
};
typedef Node *LinkList;

struct BigDec{
    LinkList Head;
    //int dot;  dot=1
    BigDec(int n = 500){
        int i = n;
        LinkList L,s;
        L = this->Head = new Node();
        L->nex = L->pre = L;
        while(i--){
            s = new Node(0, L->nex, L);
            L->nex->pre = s;
            L->nex = s;
        }
    }

    BigDec operator * (const long long rsh){
        LinkList pa= this->Head->pre;
        long long s = 0;
        while(pa != this->Head){
            long long x = rsh*(pa->elem);
            pa->elem = (x+s)%10;
            s = (x+s)/10;
            pa = pa->pre;
        }
        this->Head->elem += s;
        return *this;
    }

    BigDec operator / (const long long rsh){
        LinkList pa = this->Head->nex;
        long long s = this->Head->elem;
        if(sthis->Head->elem = 0;s = (s%rsh)*10;}
        else {this->Head->elem = s/rsh; s = (s%rsh)*10;}
        while(pa != this->Head){
            s += pa->elem;
            if(s < rsh ){ pa->elem = 0;s = (s%rsh)*10;pa = pa->nex;}
            else {pa->elem = s/rsh;s = (s%rsh)*10; pa = pa->nex;}
        }
        return *this;
    }


    BigDec operator + (const BigDec &rsh){
        LinkList pa,pb;
        pa = this->Head->pre;
        pb = rsh.Head->pre;
        int s = 0;
        while(pa!=this->Head){
            int x = (pa->elem + pb->elem);
            pa->elem = (x+s)%10;
            s = (x+s)/10;
            pa = pa->pre;pb = pb->pre;
        }
        return *this;
    }

};

typedef BigDec *LBigDec;

void BigDec_pri(BigDec &BDec, int n){//打印
    LinkList p = BDec.Head->nex;
    printf("%d.", BDec.Head->elem);
    while(n--){
        printf("%d", p->elem);
        p = p->nex;
    }
    printf("\n");
}

int main(){
    int N;
    scanf("%d", &N);
    BigDec *a = new BigDec(N+10);
    BigDec *b = new BigDec(N+10);
    a->Head->nex->elem = 5;
    *b+*a;
    long long x, y;
    for(int i = 1; i<=N*10; i++){
        x = (long long)(2*i-1)*(2*i-1);
        y = (long long)(2*i)*(2*i+1)*4;
        (*a)*x;
        (*a)/y;
        //BigDec_pri(*a);
        (*b)+(*a);
    }
    (*b)*(long long)6;
    BigDec_pri(*b,N);

}

你可能感兴趣的:(高精度计算PI值)