好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

第章高精度计算C版课件.ppt

31页
  • 卖家[上传人]:工****
  • 文档编号:591922962
  • 上传时间:2024-09-18
  • 文档格式:PPT
  • 文档大小:326.50KB
  • / 31 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 第一章第一章￿￿ ￿￿高精度计算高精度计算 ￿￿￿￿￿￿￿￿利用计算机进行数值计算,有时会遇到这样的问题:有些计算要求精度高,希望计算的数的位数可达几十位甚至几百位,虽然计算机的计算精度也算较高了,但因受到硬件的限制,往往达不到实际问题所要求的精度我们可以利用程序设计的方法去实现这样的高精度计算介绍常用的几种高精度计算的方法￿￿￿￿￿￿￿高精度计算中需要处理好以下几个问题:(1)数据的接收方法和存贮方法￿￿￿￿￿￿￿数据的接收和存贮:当输入的数很长时,可采用字符串方式输入,这样可输入数字很长的数,利用字符串函数和操作运算,将每一位数取出,存入数组中另一种方法是直接用循环加数组方法输入数据void￿init(int￿a[])￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//传入一个数组{￿￿￿￿￿￿￿￿￿￿￿￿string￿s;￿￿￿￿￿￿￿￿cin>>s;￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//读入字符串s￿￿￿￿￿￿￿￿a[0]=s.length();￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//用a[0]计算字符串s的位数￿￿￿￿￿￿￿￿for(i=1;i<=a[0];i++)￿￿￿￿￿￿￿￿￿￿a[i]=s[a[0]-i]-'0';￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//将数串s转换为数组a,并倒序存储￿}另一种方法是直接用循环加数组方法输入数据。

      2PPT学习交流 (2)￿高精度数位数的确定￿￿￿￿￿￿￿位数的确定:接收时往往是用字符串的,所以它的位数就等于字符串的长度3)￿进位,借位处理￿￿￿￿￿￿￿加法进位:c[i]=a[i]+b[i];￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿if￿(c[i]>=10)￿{￿c[i]%=10;￿++c[i+1];￿}  减法借位:if￿(a[i]

      而当两个被加数很大时,上述算法显然不能求出精确解,因此我们需要寻求另外一种方法在读小学时,我们做加法都采用竖式方法,如图1￿这样,我们方便写出两个整数相加的算法 8 5 6 + 2 5 5 1 1 1 1 图1 A3 A2 A1+ B3 B2 B1 C4 C3 C2 C1 图2￿￿￿￿￿￿￿如果我们用数组A、B分别存储加数和被加数,用数组C存储结果则上例有A[1]=6,A[2]=5,￿A[3]=8,B[1]=5,B[2]=5,B[3]=2,C[4]=1,C[3]=1,C[2]=1,C[1]=1,两数相加如图2所示4PPT学习交流 因此,算法描述如下:int￿c[100];void￿add(int￿a[],int￿b[])￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//a,b,c都为数组,分别存储被加数、加数、结果{￿￿￿￿int￿￿i=1,x=0;￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//x是进位￿￿￿￿while￿((i<=a数组长度)||(i<=b数组的长度)) {    c[i]=a[i]+b[i]+x;￿￿￿￿//第i位相加并加上次的进位    x=c[i]/10;￿￿￿￿￿￿￿￿￿￿￿￿￿//向高位进位    c[i]%=10;￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//存储第i位的值    i++;￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//位置下标变量 }}5PPT学习交流 ￿￿通常,读入的两个整数用可用字符串来存储,程序设计如下:#include#include#includeusing￿namespace￿std;int￿main(){char￿a1[100],b1[100];￿￿int￿a[100],b[100],c[100],lena,lenb,lenc,i,x;￿￿memset(a,0,sizeof(a));￿￿memset(b,0,sizeof(b));￿￿memset(c,0,sizeof(c));￿￿gets(a1);￿gets(b1);￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//输入加数与被加数￿￿lena=strlen(a1);￿￿lenb=strlen(b1);￿￿for￿(i=0;i<=lena-1;i++)￿a[lena-i]=a1[i]-48;￿￿￿￿//加数放入a数组 ￿for￿(i=0;i<=lenb-1;i++)￿b[lenb-i]=b1[i]-48;￿￿//加数放入b数组￿￿lenc￿=1;￿￿x=0;￿￿6PPT学习交流 ￿while￿(lenc￿<=lena||lenc￿<=lenb){   c[lenc]=a[lenc]+b[lenc]+x;￿￿￿￿￿//两数相加   x=c[lenc]/10;   c[lenc]%=10;￿￿￿￿￿￿￿ lenc++;}c[lenc]=x;￿if￿(c[lenc]==0)lenc--;￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//处理最高进位for￿(i=lenc;i>=1;i--)￿cout<

      输入两个正整数,求它们的差算法分析】￿￿￿￿￿￿￿类似加法,可以用竖式求减法在做减法运算时,需要注意的是:被减数必须比减数大,同时需要处理借位高精度减法的参考程序:  #include#include#includeusing￿namespace￿std;int￿main(){int￿a[256],b[256],c[256],lena,lenb,lenc,i;char￿n[256],n1[256],n2[256];memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(c,0,sizeof(c));￿8PPT学习交流 printf("Input￿minuend:");￿￿￿￿gets(n1);￿￿￿//输入被减数printf("Input￿subtrahend:");￿gets(n2);￿￿￿//输入减数￿if￿(strlen(n1)n2时,返回正整数;n11))￿lenc--;￿￿￿//最高位的0不输出  ￿￿for￿(i=lenc;i>=1;i--)￿cout<

      输入两个正整数,求它们的积算法分析】￿￿￿￿￿￿  类似加法,可以用竖式求乘法在做乘法运算时,同样也有进位,同时对每一位进行乘法运算时,必须进行错位相加,如图3、图4  分析c数组下标的变化规律,可以写出如下关系式:ci￿=￿c’i￿+c”i￿+…由此可见,c￿i跟a[i]*b[j]乘积有关,跟上次的进位有关,还跟原c￿i的值有关,分析下标规律,有c[i+j-1]=￿a[i]*b[j]+￿x￿+￿c[i+j-1];￿x=c[i+j-1]/10￿;￿c[i+j-1]%=10; 8 5 6 × 2 5 4 2 8 0 1 7 1 2 2 1 4 0 0 图3A 3 A 2 A 1 × B 2 B 1 C’4C’3 C’2 C’1 C”5C”4C”3C”2 C 6 C 5 C 4 C 3 C 2 C 1 图411PPT学习交流 高精度乘法的参考程序:#include#include#includeusing￿namespace￿std;int￿main(){￿￿￿￿char￿a1[100],b1[100];￿￿￿￿int￿a[100],b[100],c[100],lena,lenb,lenc,i,j,x;￿￿￿￿memset(a,0,sizeof(a));￿￿￿￿memset(b,0,sizeof(b));￿￿￿￿memset(c,0,sizeof(c));￿￿￿￿gets(a1);gets(b1);￿￿￿￿lena=strlen(a1);lenb=strlen(b1);￿￿￿￿for￿(i=0;i<=lena-1;i++)￿a[lena-i]=a1[i]-48;￿￿￿￿for￿(i=0;i<=lenb-1;i++)￿b[lenb-i]=b1[i]-48;￿￿12PPT学习交流 ￿for￿(i=1;i<=lena;i++){￿￿￿￿￿x=0;￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//用于存放进位￿￿￿￿￿for￿(j=1;j<=lenb;j++)￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//对乘数的每一位进行处理￿￿￿￿￿{￿￿￿c[i+j-1]=a[i]*b[j]+x+c[i+j-1];￿//当前乘积+上次乘积进位+原数 ￿￿￿￿￿￿￿x=c[i+j-1]/10;￿￿￿c[i+j-1]￿%=￿10;￿￿￿￿￿}￿￿￿￿￿c[i+lenb]=x;￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//进位}lenc=lena+lenb;while￿(c[lenc]==0&&lenc>1)￿￿￿￿￿￿￿//删除前导0lenc--;for￿(i=lenc;i>=1;i--)cout<

      输入两个正整数,求它们的商(做整除)算法分析】￿￿￿￿￿￿￿做除法时,每一次上商的值都在0~9,每次求得的余数连接以后的若干位得到新的被除数,继续做除法因此,在做高精度除法时,要涉及到乘法运算和减法运算,还有移位处理当然,为了程序简洁,可以避免高精度除法,用0~9次循环减法取代得到商的值这里,我们讨论一下高精度数除以单精度数的结果,采取的方法是按位相除法14PPT学习交流 #include#include#includeusing￿namespace￿std;int￿main(){char￿a1[100],c1[100];￿￿int￿a[100],c[100],lena,i,x=0,lenc,b;￿￿memset(a,0,sizeof(a));￿￿memset(c,0,sizeof(c));￿￿gets(a1);￿￿cin>>b;￿￿lena=strlen(a1);￿￿for￿(i=0;i<=lena-1;i++)  a[i+1]=a1[i]-48;15PPT学习交流 ￿￿for￿(i=1;i<=lena;i++)￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//按位相除{c[i]=(x*10+a[i])/b;￿￿￿￿x=(x*10+a[i])%b;} ￿lenc=1;￿￿￿￿while￿(c[lenc]==0&&lenc

      例如图5就是采用4位保存的除法运算,其他运算也类似具体程序可以修改上述例题予以解决,程序请读者完成示例:123456789￿÷45￿=￿1’￿2345’￿6789￿÷￿45￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿=￿274’￿3484∵￿1￿/￿45￿=￿0￿￿,￿1%45=1∴￿取12345￿/￿45￿=￿274￿￿￿∵￿￿12345￿%￿45￿=￿15∴￿取156789/45￿=￿3484￿￿￿∴￿答案为2743484,￿余数为156789%45￿=￿9￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿图517PPT学习交流 ￿【例5】高精除以高精,求它们的商和余数算法分析】￿￿￿￿￿高精除以低精是对被除数的每一位(这里的“一位”包含前面的余数,以下都是如此)都除以除数,而高精除以高精则是用减法模拟除法,对被除数的每一位都减去除数,一直减到当前位置的数字(包含前面的余数)小于除数(由于每一位的数字小于10,所以对于每一位最多进行10次计算)具体实现程序如下:18PPT学习交流 ￿#include#includeusing￿namespace￿std;int￿a[101],b[101],c[101],d,i;￿￿￿void￿init(int￿a[])￿{￿￿￿￿string￿s;￿cin>>s;￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//读入字符串s￿a[0]=s.length();￿￿￿￿￿￿￿￿￿￿￿//用a[0]计算字符串￿s的位数￿for(i=1;i<=a[0];i++)a[i]=s[a[0]-i]-'0';￿￿￿￿￿￿￿￿￿￿//将数串s转换为数组a,并倒序存储.￿}void￿print(int￿a[])￿￿￿￿￿￿￿￿￿￿￿￿￿￿//打印输出{if￿(a[0]==0){cout<<0<0;i--)￿cout<b则为1,ab[0])￿return￿1;￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//a的位数大于b则a比b大￿if(a[0]0;i--)￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//从高位到低位比较￿{if￿(a[i]>b[i])￿return￿1;￿if￿(a[i]

      ￿}￿void￿numcpy(int￿p[],int￿q[],int￿det)￿￿￿￿￿￿//复制p数组到q数组从det开始的地方{for￿(int￿i=1;i<=p[0];i++)￿q[i+det-1]=p[i];q[0]=p[0]+det-1;}20PPT学习交流 ￿void￿jian(int￿a[],int￿b[])￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//计算a=a-b{￿int￿flag,i;￿flag=compare(a,b);￿￿￿￿￿￿￿￿￿￿￿￿￿￿//调用比较函数判断大小￿if￿(flag==0)￿{a[0]=0;return;}￿￿￿//相等￿if(flag==1)￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//大于￿￿￿{for(i=1;i<=a[0];i++)￿{if(a[i]0&&a[a[0]]==0)￿a[0]--;￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//修正a的位数￿return;}￿}￿21PPT学习交流 ￿void￿chugao(int￿a[],int￿b[],int￿c[]){int￿tmp[101];￿c[0]=a[0]-b[0]+1;for￿(int￿i=c[0];i>0;i--){memset(tmp,0,sizeof(tmp));￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//数组清零￿numcpy(b,tmp,i);while(compare(a,tmp)>=0){c[i]++;jian(a,tmp);}￿￿//用减法来模拟}while(c[0]>0&&c[c[0]]==0)c[0]--;return￿;}22PPT学习交流 ￿int￿main(){￿￿ memset(a,0,sizeof(a));￿￿ memset(b,0,sizeof(b));￿￿ memset(c,0,sizeof(c));￿￿ init(a);init(b);￿￿ chugao(a,b,c);￿￿ print(c);￿￿ print(a);￿￿ return￿0;}23PPT学习交流 ￿【例6】回文数【问题描述】若一个数(首位不为零)从左向右读与从右向左读都是一样,我们就将其称之为回文数。

      例如:给定一个￿10进制数￿56,将￿56加￿65(即把56从右向左读),得到￿121是一个回文数又如,对于10进制数87,￿STEPl:￿87+78=￿165￿STEP2:￿165+561=￿726￿STEP3:￿726+627=1353￿STEP4:1353+3531=4884￿  在这里的一步是指进行了一次N进制的加法,上例最少用了4步得到回文数4884￿  写一个程序,给定一个N(2<N<=10或N=16)进制数￿M.求最少经过几步可以得到回文数如果在30步以内(包含30步)不可能得到回文数,则输出“Impossible”￿【输入样例】:9￿87【输出样例】:6【算法分析】￿￿N进制运算 ￿￿1、当前位规范由%10改为%￿n ￿￿2、进位处理由/10改为/n ￿￿3、其他运算规则不变24PPT学习交流 ￿【参考程序】#include#includeusing￿namespace￿std;int￿n,a[101],b[101],ans,i;void￿init(int￿a[])￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//将数串s转化为整数数组a{￿string￿s;￿￿￿ cin>>n>>s;￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//读入字符串s￿￿￿ memset(a,0,sizeof(a));￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//数组a清0￿￿￿ a[0]=s.length();￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//用a[0]计算字符串s的位数￿￿￿ for(i=1;i<=a[0];i++)￿￿￿￿if(s[a[0]-i]>='0'&&s[a[0]-i]<='9')￿￿￿￿￿a[i]=s[a[0]-i]-'0';￿￿￿￿￿￿else￿a[i]=s[a[0]-i]-'A'+10;}bool￿check(int￿a[])￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//判别整数数组a是否为回文数{￿for(i=1;i<=a[0];i++)￿￿￿￿if(a[i]!=a[a[0]-i+1])return￿false;￿￿ return￿true;}25PPT学习交流 ￿void￿￿jia(int￿a[])￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//整数数组a与其反序数b进行n进制加法运算{for(int￿i=1;i<=a[0];i++)b[i]=a[a[0]-i+1];￿￿￿￿￿￿//反序数bfor(int￿i=1;i<=a[0];i++)￿a[i]+=b[i];￿￿￿￿￿￿￿￿￿￿￿￿￿￿//逐位相加for(int￿i=1;i<=a[0];i++)￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿//处理进位{a[i+1]+=a[i]/n;a[i]%=n;}￿if(a[a[0]+1]>0)￿a[0]++;￿￿￿￿//修正新的a的位数(a+b最多只能的一个进位)￿}int￿main(){ init(a);if(check(a)){cout<<0<

      输入样例】ni.in￿￿￿10【输出样例】ni.out￿￿￿36288002、求A/B高精度值【问题描述】￿￿￿￿计算A/B的精确值,设A,B是以一般整数输入,计算结果精确小数后20位输入样例】ab.in￿￿￿￿4￿￿3【输出样例】ab.out4/3=1.33333333333333333333【输入样例】ab.in￿￿￿￿6￿￿5【输出样例】ab.out6/5=1.227PPT学习交流 3、求n累加和【问题描述】用高精度方法,求s=1+2+3+……+n的精确值(n以一般整数输入)输入样例】ja.in￿￿￿￿10【输出样例】ja.out￿￿￿￿554、阶乘和(sum.pas)【问题描述】已知正整数N(N<=100),设S=1!+2!+3!+...N!其中"!"表示阶乘,即N!=1*2*3*……*(N-1)*N,如:3!=1*2*3=6请编程实现:输入正整数N,输出计算结果S的值输入样例】sum.in4【输出样例】sum.out335、高精度求积(MULTIPLY.PAS)【问题描述】输入两个高精度正整数M和N(M和N均小于100位)问题求解】求这两个高精度数的积输入样例】MULTIPLY.IN363【输出样例】MULTIPLY.OUT10828PPT学习交流 6、天使的起誓(YUBIKILI.pas)【问题描述】TENSHI非常幸运的被选为掌管智慧之匙的天使。

      在正式任职之前,她必须和其他新当选的天使一样,要宣誓宣誓仪式是每位天使各自表述自己的使命,她们的发言稿被放在N个呈圆形排列的宝盒中这些宝盒按顺时针方向被编上号码1、2、3……、N-1、N一开始天使们站在编号为N的宝盒旁她们各自手上都有一个数字,代表她们自己的发言稿所在的盒子是从1号盒子开始按顺时针方向的第几个例如:有7个盒子,那么如果TENSHI手上的数字为9,那么她的发言稿所在盒子就是第2个现在天使们开始按照自己手上的数字来找发言稿,先找到的就可以先发言TENSHI一下子就找到了,于是她最先上台宣誓:“我将带领大家开启NOI之门……”TENSHI宣誓结束以后,陆续有天使上台宣誓可是有一位天使找了好久都找不到她的发言稿,原来她手上的数字M非常大,她转了好久都找不到她想找的宝盒问题求解】请帮助这位天使找到她想找的宝盒的编号输入格式】从文件YUBIKILI.IN的第一、二行分别读入正整数N和M,其中N、M满足  2￿≤￿N￿≤￿108,2￿≤￿M￿≤￿101000【输出格式】把所求宝盒的编号输出到文件YUBIKILI.OUT,文件只有一行(包括换行符)样例一YUBIKILI.IN￿79YUBIKILI.OUT2样例二YUBIKILI.IN11108YUBIKILI.OUT929PPT学习交流 7、Hanoi双塔问题(Noip2007)【问题描述】给定A、B、C三根足够长的细柱,在A柱上放有2n个中间有孔的圆盘,共有n个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的(下图为n=3的情形)。

      现要将这些圆盘移到C柱上,在移动过程中可放在B柱上暂存要求:(1)每次只能移动一个圆盘;(2)A、B、C三根细柱上的圆盘都要保持上小下大的顺序;任务:设An为2n个圆盘完成上述任务所需的最少移动次数,对于输入的n,输出An输入格式】输入文件hanoi.in为一个正整数n,表示在A柱上放有2n个圆盘输出格式】输出文件hanoi.out仅一行,包含一个正整数,￿为完成上述任务所需的最少移动次数An样例一hanoi.in￿1hanoi.out2样例二hanoi.in￿￿￿￿￿￿￿￿hanoi.out2￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿￿6【限制】￿￿￿￿对于50%的数据,1<=n<=25￿￿￿￿对于100%的数据,1<=n<=200【提示】设法建立An与An-1的递推关系式30PPT学习交流 此课件下载可自行编辑修改,供参考!感谢您的支持,我们努力做得更好!31PPT学习交流 。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.