题意
用双向循环链表为存储结构解决高进度pi问题。pi值要精确到第几位,就输出到第几位。
思路
首先给出我们计算pi的理论依据
行了,从这个结构上就可以看出来,要有两个链表,一个存放一项的值(不断迭代),一个存放这些项的和(也不断迭代)
当然链表的每一个节点存放一个数位。其实用数组也是可以的。
既然是精度很高,那么肯定是要手动加减乘除了。
居然调了好几次才把这加减乘除搞定
代码
细节挺多,不一一说了。
//高精度计算PI
#include <stdio.h>
#include <stdlib.h>
const int maxn=600;
typedef struct Node{
int data;
struct Node *next,*prev;
}*DLinklist,Dnode;
DLinklist Dhead_create(int num)
{
DLinklist head=(DLinklist)malloc(sizeof(Dnode));
head->next=head->prev=head;///头插法 注意初始化条件
head->data=2;
int i;
for(i=1;i<=num;i++)
{
DLinklist now=(DLinklist)malloc(sizeof(Dnode));
now->data=0,now->next=head->next;
if(head->next) head->next->prev=now;
head->next=now,now->prev=head;
}
return head;
}
void cal_pi(DLinklist s,DLinklist m)
{
int i=3,j=1,cnt=0,c,d;
DLinklist temp=m->prev;
while(cnt<2000)
{
cnt++;
d=0;
for(;temp!=m;temp=temp->prev) ///乘法计算 从低位到高位 注意进位
{
c=temp->data*j+d;///此处d是进位
d=c/10;
temp->data=c%10;
}
temp->data+=d;///注意对第一位的数字的进位
temp=m,d=0;
while(1)///除法计算 从高位到低位
{
c=temp->data+d*10;///手动模拟除法
d=c%i;
temp->data=c/i;
temp=temp->next;
if(temp==m) break;
}
temp=m->prev,d=0;
DLinklist ptr=s->prev;
while(1)
{
c=temp->data+ptr->data+d;
d=c/10;
ptr->data=c%10;
temp=temp->prev,ptr=ptr->prev;
if(ptr==s->prev) break;
}
i+=2,j++;
}
}
void Destroy_list(DLinklist head)///循环链表销毁
{
DLinklist temp=head->next,pre=head;
while(temp!=head)
{
pre=temp,temp=temp->next;
free(pre);
}
free(head);
}
int main(){
DLinklist s,m;
int n;
s=Dhead_create(maxn),m=Dhead_create(maxn);
cal_pi(s,m);
scanf("%d",&n);
printf("%d.",s->data);
DLinklist p = s->next;
for(int i = 0;i < n;i++)
{
printf("%d",p->data);
p=p->next;
}
printf("\n");
Destroy_list(s),Destroy_list(m);
return 0;
}