高精度计算(一)
一、高精度计算中需处理好以下问题
•数据的接收与存储;
•计算结果位数的确定;
•进位、借位、商和余数的处理
•运算结果的输出
1.数据的接收方法和存贮方法
数据的接收和存贮:当输入的数很长时,可采用字符串方式输入,这样可输入数字很长的数,利用字符串函数和操作运算,将每一位数取出,存入数组中. Type numtype=array[1..500]of word;{整数数组类型} Var a,b:numtype; {a和b为整数数组} la,lb:integer; {整数数组a的长度和b的长度} s:string; {输入数串} 将数串s转化为整数数组a的方法如下: readln(s); la:=length(s); for i:=1 to la do a[la-i+1]:=ord(s[i])-ord('0');
另一种方法是直接用循环加数组方法输入数据. Type arr= array[1..100] of integer; prucedure readdata(var int:arr); var ch:char; i,k:integer; begin read(ch);k:=0; while ch in['0'..'9'] do begin inc(k);int[k]:=ord(ch)-ord(‘0’); read(ch); end; end;
储存数据一律用数组。根据不同的需要,数据的储存可分正向与反向两种。以输入数1234为例: ①正向储存:数位权的大小与储存数组的下标的大小一致 下标大 下标小 数组各元素 a[4] a[3] a[2] a[1] 所存的数字 1 2 3 4 最高位 最低位 ②反向储存:数位权的大小与储存数组的下标的大小相反 下标小 下标大 数组各元素 a[1] a[2] a[3] a[4] 所存的数字 1 2 3 4 最高位 最低位 加法、减法、乘法的运算是从低位开始的,所以数据储存采取正向储存比较方便。
2.计算结果位数的确定
•两数之和的位数最大为较大的数的位数加1。
•乘积的位数最大为两个因子的位数之和。
3.进位、借位、商和余数的处理
加法进位: C[i]:= A[i]+B[i]; if C[i]>=10 then begin C[i]:= C[i] mod 10; C[i+1]:= C[i+1]+1 end; 减法借位: if a[i]<b[i] then begin a[i+1]:=a[i+1]-1;a[i]:=a[i]+10 end c[i]:=a[i]-b[i] 乘法进位: C[i+j-1]:= A[i]*B[j]+ x DIV 10+ C[i+j-1]; x:= C[i+j-1] div 10; C[i+j-1]:= C[i+j-1] mod 10 商和余数处理: 视被除数和除数的位数情况进行处理.
4.运算结果的输出
输出要注意三点: 数据是正向储存,用递减循环输出;数据是反向储存,用递增循环输出 TP是先定义,后运算的。无法根据机器的运算的结果来定义数组的大小,所以一般定义数组大一些,这样就增加在有效数字前有一些无用的0操作。
在输出时这些在有效数字前无用的0不能输出。一般在输出有效数字前采用:while a[i]=0 do i:=i-1(正向储存) 或while a[i]=0 do i:=i+1(反向储存) 如是用一个字节储存多位数字,输出时要用0来补位。