高精度计算PI值实验

前言:此文章用于高精度计算pi值,详细介绍了函数代码实现,可能比较繁琐,只需要代码的可以 翻到文末完整代码处,另外计算pi值的函数中会用到较多高数方面知识,如果不懂就得劳烦大家自行查阅相关资料。

一、需求分析

1、输入的形式和输入值的范围:输入一个正整数n,表示小数点后精确的位数,小于500

2、输出的形式:输出PI值,精确到小数点后n位,最后还要输出一个回车

3、程序所能达到的功能:高精度计算PI的值,并将其按位储存在一个双链表中

4、测试数据:

二、概要设计

为了实现上述操作,应以双向链表为存储结构。

1.基本操作:

void Create() 创建双链表,初始化值全部为0;

void he()    若链表存在,实现将两个链表对应项相加并储存到第一个链表中(注意进位)

void cheng()  若链表存在,实现将链表每位乘以个x并保存回去并注意进位

void chu()    若链表存在,实现将链表每一位对x的余数乘10加到本位

DLinkList pi()  实现计算高精度计算pi值

void show() 实现将链表的前n位输出,并按要求在最后输出一个换行符

2.本程序包含三个模块:

(1)主程序模块;

(2)构造链表并初始化模块;

(3)计算pi并输出模块;

(4)模块调用图:

主程序模块

构造链表并初始化模块

计算pi并输出模块

{

调用了和函数,积函数,商函数(具体作用见1)

}

最后调用show函数进行输出模块

 (三) 详细设计

1.元素类型,结点类型和指针类型:

typedef struct DNode

{

    int data;

    struct DNode* next;

    struct DNode* pre;

}DNode, * DLinkList;      

2.每个模块的分析:

(1)主程序模块:

int main()

{

    int n;

    scanf_s("%d", &n);

    DLinkList l, t;

    Create(&l, 999);                       

    Create(&t, 999);

    l=pi(l, t);

    printf("3.");

    show(l, n);                            

    return 0;

}

(2)构造链表并初始化模块;

void Create(DLinkList* L, int n)

{

    DLinkList s;

    *L = (DLinkList)malloc(sizeof(DNode));          

    (*L)->pre = (*L)->next = NULL;                    

    for (; n > 0; n--) {                                

        s = (DLinkList)malloc(sizeof(DNode));       

        s->data = 0;                                

        s->next = (*L)->next;

        if ((*L)->next != NULL) {                     

            (*L)->next->pre = s;

        }

        (*L)->next = s;                            

        s->pre = *L;

    }

}                      //创建初值为0的双链表

(3)计算pi并输出模块

DLinkList pi(DLinkList l, DLinkList t ) {

    t->next->data = 5;                           

    he(l, t);

    int  i, a, b;

    for (i = 1; i < 5000; i++) {                          

        a = (2 * i - 1) * (2 * i - 1);

        b = 8 * i * (2 * i + 1);

        cheng(t, a);

        chu(t, b);

        he(l, t);

    }             //泰勒展开,中间用到了递归(重要的pi值计算算法)

    cheng(l, 6);

    return l;

}

3.计算pi中用到的函数

  a.和函数 

 void he(DLinkList l, DLinkList t)

{

    DLinkList p, q;

    int a = 0;

    p = l;

    q = t;

    while (p->next != NULL) {                         

        p->next->data = p->next->data + q->next->data;

        p = p->next;

        q = q->next;

    }

    while (p->pre != NULL) {                         

        p->data += a;

        a = p->data / 10;

        p->data %= 10;

        p = p->pre;

    }

}                 //将两个链表的元素对应项加并保存到第一个链表里,还要注意进位

   b.积函数

   void cheng(DLinkList t, int x)

{

    DLinkList p;

    int a = 0;

    p = t;

    while (p->next != NULL) {                         

        p->next->data *= x;

        p = p->next;

    }

    while (p->pre != NULL) {                         

        p->data += a;

        a = p->data / 10;

        p->data %= 10;

        p = p->pre;

    }

}                         //将链表里每个元素乘以x并保存回去,注意进位

     c.商函数

void chu(DLinkList t, int x)

{

    DLinkList p;

    int a = 0;

    p = t->next;

    while (p != NULL) {

        p->data += a * 10;                          

        a = p->data % x;

        p->data /= x;

        p = p->next;

    }

}                       //将链表每一位对x的余数乘10加到本位

(4)函数调用关系图

main()

{

void Create()

DLinkList pi()

{

void he()

void cheng()

void chu()

}

void show()

}

3.完整的程序:

#include <stdio.h>
#include <stdlib.h>

typedef struct DNode
{
    int data;
    struct DNode* next;
    struct DNode* pre;
}DNode, * DLinkList;

void Create(DLinkList* L, int n)
{
    DLinkList s;
    *L = (DLinkList)malloc(sizeof(DNode));          
    (*L)->pre = (*L)->next = NULL;                    
    for (; n > 0; n--) {                                
        s = (DLinkList)malloc(sizeof(DNode));       
        s->data = 0;                                
        s->next = (*L)->next;
        if ((*L)->next != NULL) {                     
            (*L)->next->pre = s;
        }
        (*L)->next = s;                            
        s->pre = *L;
    }
}

void show(DLinkList L, int n)
{
    DNode* p = L;
    int i = 0;
    while (p->next != NULL && i < n) {
        p = p->next;
        printf("%d", p->data);
        i++;
    }
    printf("\n");
}

void he(DLinkList l, DLinkList t)
{
    DLinkList p, q;
    int a = 0;
    p = l;
    q = t;
    while (p->next != NULL) {                         
        p->next->data = p->next->data + q->next->data;
        p = p->next;
        q = q->next;
    }
    while (p->pre != NULL) {                         
        p->data += a;
        a = p->data / 10;
        p->data %= 10;
        p = p->pre;
    }
}

void cheng(DLinkList t, int x)
{
    DLinkList p;
    int a = 0;
    p = t;
    while (p->next != NULL) {                         
        p->next->data *= x;
        p = p->next;
    }
    while (p->pre != NULL) {                         
        p->data += a;
        a = p->data / 10;
        p->data %= 10;
        p = p->pre;
    }
}

void chu(DLinkList t, int x)
{
    DLinkList p;
    int a = 0;
    p = t->next;
    while (p != NULL) {
        p->data += a * 10;                          
        a = p->data % x;
        p->data /= x;
        p = p->next;
    }
}


DLinkList pi(DLinkList l, DLinkList t ) {
    t->next->data = 5;                           
    he(l, t);
    int  i, a, b;
    for (i = 1; i < 5000; i++) {                          
        a = (2 * i - 1) * (2 * i - 1);
        b = 8 * i * (2 * i + 1);
        cheng(t, a);
        chu(t, b);
        he(l, t);
    }
    cheng(l, 6);
    return l;
}

int main()
{
    int n;
    scanf_s("%d", &n);
    DLinkList l, t;
    Create(&l, 999);                       
    Create(&t, 999);
    l=pi(l, t);
    printf("3.");
    show(l, n);                            
    return 0;
}

(四) 程序使用说明及测试结果

1.程序使用说明

(1)本程序的运行环境为VC6.0。

(2)输入想要输出的pi后保留位数

2.运行界面

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值