高精度计算由于计算机具有运算速度快,计算精度高的特点,许多过去由人来完成的烦琐、复杂的数学计算,现在都可以由计算机来代替。
计算机计算结果的精度,通常要受到计算机硬件环境的限制。
例如,pascal 要计算的数字超过19位,计算机将按浮点形式输出;另一方面,计算机又有数的表示范围的限制,在一般的微型计算机上,实数的表示范围为l0-38 -l038。
例如,在计算N!时,当N=21时计算结果就超过了这个范围,无法计算了。
这是由计算机的硬件性质决定的,但是,我们可以通过程序设计的方法进行高精度计算(多位数计算)。
学习重点1、掌握高精度加、减、乘、除法。
3、理解高精度除法运算中被除数、除数、商和余数之间的关系。
4、能编写相应的程序,解决生活中高精度问题。
学习过程一、高精度计算的基本方法用free pascal程序进行高精度计算,首先要处理好以下几个基本问题:【数据的输入与保存】(1)一般采用字符串变量存储数据,然后用length函数测量字符串长度确定其位数。
(2)分离各位数位上的数字分离各数位上的数通常采用正向存储的方法。
以“163848192”为例,见下表:A[9] A[8] A[7] A[6] A[5] A[4] A[3] A[2] A[1]1 6 3 8 4 8 1 9 2基本原理是A[1]存放个位上的数字,A[2]存放十位上的数字,……依此类推。
即下标小的元素存低位上的数字,下标大的元素存高位上的数字,这叫“下标与位权一致”原则。
【计算结果位数的确定】(1)高精度加法:和的位数为两个加数中较大数的位数+1。
(2)高精度减法:差的位数为被减数和减数中较大数的位数。
(3)高精度乘法:积的位数为两个相乘的数的位数之和。
(4)高精度除法:商的位数按题目的要求确定。
【计算顺序与结果的输出】高精度加、减、乘法,都是从低位到高位算起,而除法相反。
输出结果都是从高位到低位的顺序,注意:高位上的零不输出(整数部分是零除外)。
高精度加法【参考程序】var a,b:array[1..10000] of byte;i,w,la,lb:integer;s1,s2:ansistring;beginreadln(s1);la:=length(s1);readln(s2);lb:=length(s2);for i:=1 to la do a[i]:=ord(s1[la+1-i])-48;for i:=1 to lb do b[i]:=ord(s2[lb+1-i])-48;if lb>la then la:=lb;for i:=1 to la do begina[i]:=a[i]+b[i]+w;w:=a[i] div 10;a[i]:=a[i] mod 10;end;if w>0 then begin la:=la+1;a[la]:=w;w:=0;end;for i:=la downto 1 do write(a[i]);end.高精度减法【参考程序】var a,b:array[1..10000] of integer;i,la,lb:integer;s,s1,s2:ansistring;beginreadln(s1);la:=length(s1);readln(s2);lb:=length(s2);if (la<lb) or (la=lb) and (s1<s2) then beginwrite('-');s:=s1;s1:=s2;s2:=s;la:=length(s1);lb:=length(s2);end;for i:=1 to la do a[i]:=ord(s1[la+1-i])-48;for i:=1 to lb do b[i]:=ord(s2[lb+1-i])-48;for i:=1 to la do begina[i]:=a[i]-b[i];if a[i]<0 then begin a[i+1]:=a[i+1]-1;a[i]:=a[i]+10;end; end;while (a[la]=0) and (la>1) do dec(la);for i:=la downto 1 do write(a[i]);end.高精度乘法【参考程序】var a,b,c:array[1..10000] of byte;i,j,x,w,la,lb,lc:integer;s1,s2:ansistring;beginreadln(s1);la:=length(s1);readln(s2);lb:=length(s2);for i:=1 to la do a[i]:=ord(s1[la+1-i])-48;for i:=1 to lb do b[i]:=ord(s2[lb+1-i])-48;for i:=1 to la dofor j:=1 to lb do beginw:=i+j-1;x:=a[i]*b[j];c[w]:=c[w]+x mod 10;c[w+1]:=c[w+1]+x div 10+c[w] div 10;//双进位c[w]:=c[w] mod 10;end;lc:=la+lb;if c[lc]=0 then lc:=lc-1;for i:=lc downto 1 do write(c[i]);end.上面的算法是常见高精度乘法的一般形式,在高精度乘法中还存在许多特殊的算法例如计算高精度N!,求M的N次方幂等。
这里给出这两个问题的程序段,相信你能从其中发现更多的高精度乘法的规律。
求N!的程序var a,b,c:array[1..50000] of byte;i,j,k,x,w,n,t,la,lb,lc:integer;beginread(n);a[1]:=1;la:=1;for i:=2 to n do begint:=i;lb:=0;repeatlb:=lb+1;b[lb]:=t mod 10;t:=t div 10;until t=0;for j:=1 to la dofor k:=1 to lb do beginx:=a[j]*b[k];w:=j+k-1;c[w]:=c[w]+x mod 10;c[w+1]:=c[w+1]+x div 10+c[w] div 10;c[w]:=c[w] mod 10;end;lc:=la+lb;while (c[lc]=0) and (lc>1) do lc:=lc-1;a:=c;la:=lc;fillchar(c,sizeof(c),0);//c数组一定要清零end;for i:=la downto 1 do write(a[i]);end.var a:array[1..10000] of longint;i,j,w,l,n:integer;beginread(n);a[1]:=1;l:=1;for i:=2 to n do beginfor j:=1 to l do begina[j]:=a[j]*i+w;w:=a[j] div 10000;a[j]:=a[j] mod 10000;end;if w>0 then begin l:=l+1;a[l]:=w;w:=0;end; end;write(a[l]);for i:=l-1 downto 1 doif a[i]>=1000 then write(a[i])else if a[i]>=100 then write('0',a[i]) else if a[i]>=10 then write('00',a[i]) else write('000',a[i]);end.M的N次方幂程序var a,b,c:array[1..50000] of byte;i,j,k,x,w,m,n,la,lb,lc:integer;beginread(m,n);repeatla:=la+1;a[la]:=m mod 10;m:=m div 10;until m=0;b:=a;lb:=la;for i:=2 to n do beginfor j:=1 to la dofor k:=1 to lb do beginx:=a[j]*b[k];w:=j+k-1;c[w]:=c[w]+x mod 10;c[w+1]:=c[w+1]+x div 10+c[w] div 10; c[w]:=c[w] mod 10;end;lc:=la+lb;if c[lc]=0 then lc:=lc-1;a:=c;la:=lc;fillchar(c,sizeof(c),0);end;for i:=la downto 1 do write(a[i]);end.var a:array[1..10000] of longint;i,j,w,m,n,l:integer;beginread(m,n);a[1]:=m;l:=1;for i:=2 to n do beginfor j:=1 to l do begina[j]:=a[j]*m+w;w:=a[j] div 10000;a[j]:=a[j] mod 10000;end;if w>0 then begin l:=l+1;a[l]:=w;w:=0;end;end;write(a[l]);for i:=l-1 downto 1 doif a[i]>=1000 then write(a[i])else if a[i]>=100 then write('0',a[i])else if a[i]>=10 then write('00',a[i])else write('000',a[i]);End.【练一练】【问题描述】N的阶乘值问题(JSOI2004小学组复赛第3题)阶乘是数学中的一种运算,N的阶乘表示为:N!=1*2*3*4*……*N编写程序,根据一个给出的N,求得其阶乘中所有数字之和P。
并判断P是否为素数。
【输入输出】输入:键盘输入一个自然数N(1<=N<=100)。
输出:N的阶乘值的所有数字之和P,若P为素数输出“T”,否则输出“F”。
[样例1]输入:5输出:3 T[样例2]输入:20输出:54 F【想一想】N!的高精度乘法运算中和被乘数相比较,乘数是一个什么样的数,做这一类的题目有什么规律?★印度国王的棋盘(JSOI2001小学组第3题)[问题描述]:这是一个有名的古代故事。
有一个数学家发明了一种棋盘献给了印度国王,数学家看国王非常欢喜,就向国王提出了奖赏的要求:在棋盘的第一格放一粒米,第二格放二粒米,第三格放四粒米,第四格放八粒米,.....也就是说每一格都放进了比前一格多一倍的米。