Pascal高精度运算(乘除法)

合集下载

高精度加减乘除算法

高精度加减乘除算法

⾼精度加减乘除算法⾼精度运算所谓的⾼精度运算,是指参与运算的数(加数,减数,因⼦……)范围⼤⼤超出了标准数据类型(整型,实型)能表⽰的范围的运算。

例如,求两个200位的数的和。

这时,就要⽤到⾼精度算法了。

在这⾥,我们先讨论⾼精度加法。

⾼精度运算主要解决以下三个问题:基本⽅法1、加数、减数、运算结果的输⼊和存储运算因⼦超出了整型、实型能表⽰的范围,肯定不能直接⽤⼀个数的形式来表⽰。

在Pascal中,能表⽰多个数的数据类型有两种:数组和字符串。

(1)数组:每个数组元素存储1位(在优化时,这⾥是⼀个重点!),有多少位就需要多少个数组元素;⽤数组表⽰数的优点:每⼀位都是数的形式,可以直接加减;运算时⾮常⽅便⽤数组表⽰数的缺点:数组不能直接输⼊;输⼊时每两位数之间必须有分隔符,不符合数值的输⼊习惯;(2)字符串:字符串的最⼤长度是255,可以表⽰255位。

⽤字符串表⽰数的优点:能直接输⼊输出,输⼊时,每两位数之间不必分隔符,符合数值的输⼊习惯;⽤字符串表⽰数的缺点:字符串中的每⼀位是⼀个字符,不能直接进⾏运算,必须先将它转化为数值再进⾏运算;运算时⾮常不⽅便;(3)因此,综合以上所述,对上⾯两种数据结构取长补短:⽤字符串读⼊数据,⽤数组存储数据:var s1,s2:string;a,b,c:array [1..260] of integer;i,l,k1,k2:integer;beginwrite('input s1:');readln(s1);write('input s2:');readln(s2);{————读⼊两个数s1,s2,都是字符串类型}l:=length(s1);{求出s1的长度,也即s1的位数;有关字符串的知识。

}k1:=260;for i:=l downto 1 dobegina[k1]:=ord(s1)-48;{将字符转成数值}k1:=k1-1;end;k1:=k1+1;{————以上将s1中的字符⼀位⼀位地转成数值并存在数组a中;低位在后(从第260位开始),⾼位在前(每存完⼀位,k1减1)}对s2的转化过程和上⾯⼀模⼀样。

高精度计算(二)

高精度计算(二)

高精度计算(二)【例3】高精度乘法。

从键盘读入两个正整数,求它们的积。

分析:(1)、乘法运算a←a*c(a为高精度类型,c为字节型)按照乘法规则,从a的第l位开始逐位与c相乘。

在第i位乘法运算中(1≤i≤la),a的i位与c的乘积必须加上i-1位的进位(i-1位的乘积除以10的整商),然后规整积的i-l位(取i-1位的乘积对10的余数)。

procedure multiply(var a:numtype; c:byte);vari:byte;begina[1] ←a[l]*c;{第1位初始化}for i←2 to la do {逐位相乘}begina[i] ←a[i]*c;a[i] ←a[i]+a[i-l] div 10;a[i-1] ←a[i-l] mod 10end:{for}while a[1a]>=10 do {积的最高位进位}beginla←la+1;a[la] ←a[la-1] div 10;a[la-1] ←a[la-1]mod 10;end; {while}end;{multiply}(2)、乘法运算c←a*b(a,b为高精度类型,)类似加法,可以用竖式求乘法。

在做乘法运算时,同样也有进位,同时对每一位进乘法运算时,必须进行错位相加,如图3, 图4。

分析C 数组下标的变化规律,可以写出如下关系式:C i= C 'i +C ''i +…由此可见,C i跟A[i]*B[j]乘积有关,跟上次的进位有关,还跟原C i的值有关,分析下标规律,有x:= A[i]*B[j]+ x DIV 10+ C[i+j-1];C[i+j-1] := x mod 10;类似,高精度乘法的参考程序:program exam3;constmax=200;vara,b,c:array[1..max] of 0..9;n1,n2:string;lena,lenb,lenc,i,j,x:integer;beginwrite(’Input multiplier:’); readln(n1);write(’Input multiplicand:’); readln(n2);lena:=length(n1); lenb:=length(n2);for i:=1 to lena do a[lena-i+1]:=ord(n1[i])-ord(’0’);for i:=1 to lenb do b[lenb-i+1]:=ord(n2[i])-ord(’0’);for i:=1 to lena do beginx:=0;for j:=1 to lenb do begin {对乘数的每一位进行处理}x := a[i]*b[j] + x div 10 + c[i+j-1]; {当前乘积+上次乘积进位+原数}c[i+j-1] := x mod 10;end;c[i+j]:= x div 10; {进位}end;lenc:=i+j;while (c[lenc]=0) and (lenc>1) do dec(lenc);for i:=lenc downto 1 do write(c[i]);writelnend.【例4】高精度除法。

第一讲:高精度运算_1

第一讲:高精度运算_1

onst maxn=240; {c=a+b,先加,然后再处理进位} var s1,s2:string; a,b:array[1..maxn] of integer; c:array[1..maxn+1] of integer; len,len1,len2,k,j,i:integer; begin readln(s1); {输入} readln(s2); len1:=length(s1); {数据的保存} for i:= 1 to len1 do a[i]:=ord(s1[len1+1-i])-48; len2:=length(s2); for i:= 1 to len2 do b[i]:=ord(s2[len2+1-i])-48; if len1>len2 then len:=len1 else len:=len2; for i:=1 to len do c[i]:=a[i]+b[i]; for i:=1 to len do begin c[i+1]:=c[i+1]+c[i] div 10; c[i]:=c[i] mod 10; end; if c[len+1]>0 then len:=len+1; for i:=len downto 1 do write(c[i]); end.
将字符串转换为数组存储。
用a存s1,b存s2。 A[1]存个位,便于以后计算和进位处理
S1=’3 4 5 2 3 4 5’ ….a[3] a[2] a[1]
len1:=length(s1); for i:= 1 to len1 do a[i]:=ord(s1[len1+1-i])-48; len2:=length(s2); for i:= 1 to len2 do b[i]:=ord(s2[len2+1-i])-48;

大数(高精度)加减乘除取模运算

大数(高精度)加减乘除取模运算

⼤数(⾼精度)加减乘除取模运算千⾟万苦找到了⼤数(⾼精度)加减乘除取模运算的算法,有的地⽅还需要再消化消化,代码先贴出来~ include <iostream>#include <string>using namespace std;inline int compare(string str1, string str2){if(str1.size() > str2.size()) //长度长的整数⼤于长度⼩的整数return 1;else if(str1.size() < str2.size())return -1;elsereturn pare(str2); //若长度相等,从头到尾按位⽐较,compare函数:相等返回0,⼤于返回1,⼩于返回-1}//⾼精度加法string ADD_INT(string str1, string str2){string MINUS_INT(string str1, string str2);int sign = 1; //sign 为符号位string str;if(str1[0] == '-') {if(str2[0] == '-') {sign = -1;str = ADD_INT(str1.erase(0, 1), str2.erase(0, 1));}else {str = MINUS_INT(str2, str1.erase(0, 1));}}else {if(str2[0] == '-')str = MINUS_INT(str1, str2.erase(0, 1));else {//把两个整数对齐,短整数前⾯加0补齐string::size_type l1, l2;int i;l1 = str1.size(); l2 = str2.size();if(l1 < l2) {for(i = 1; i <= l2 - l1; i++)str1 = "0" + str1;}else {for(i = 1; i <= l1 - l2; i++)str2 = "0" + str2;}int int1 = 0, int2 = 0; //int2 记录进位for(i = str1.size() - 1; i >= 0; i--) {int1 = (int(str1[i]) - 48 + int(str2[i]) - 48 + int2) % 10; //48 为 '0' 的ASCII 码int2 = (int(str1[i]) - 48 + int(str2[i]) - 48 +int2) / 10;str = char(int1 + 48) + str;}if(int2 != 0) str = char(int2 + 48) + str;}}//运算后处理符号位if((sign == -1) && (str[0] != '0'))str = "-" + str;return str;}//⾼精度减法string MINUS_INT(string str1, string str2){string MULTIPLY_INT(string str1, string str2);int sign = 1; //sign 为符号位string str;if(str2[0] == '-')str = ADD_INT(str1, str2.erase(0, 1));else {int res = compare(str1, str2);if(res == 0) return "0";if(res < 0) {sign = -1;string temp = str1;str1 = str2;str2 = temp;}string::size_type tempint;tempint = str1.size() - str2.size();for(int i = str2.size() - 1; i >= 0; i--) {if(str1[i + tempint] < str2[i]) {str1[i + tempint - 1] = char(int(str1[i + tempint - 1]) - 1);str = char(str1[i + tempint] - str2[i] + 58) + str;elsestr = char(str1[i + tempint] - str2[i] + 48) + str; }for(int i = tempint - 1; i >= 0; i--)str = str1[i] + str;}//去除结果中多余的前导0str.erase(0, str.find_first_not_of('0'));if(str.empty()) str = "0";if((sign == -1) && (str[0] != '0'))str = "-" + str;return str;}//⾼精度乘法string MULTIPLY_INT(string str1, string str2){int sign = 1; //sign 为符号位string str;if(str1[0] == '-') {sign *= -1;str1 = str1.erase(0, 1);}if(str2[0] == '-') {sign *= -1;str2 = str2.erase(0, 1);}int i, j;string::size_type l1, l2;l1 = str1.size(); l2 = str2.size();for(i = l2 - 1; i >= 0; i --) { //实现⼿⼯乘法string tempstr;int int1 = 0, int2 = 0, int3 = int(str2[i]) - 48;if(int3 != 0) {for(j = 1; j <= (int)(l2 - 1 - i); j++)tempstr = "0" + tempstr;for(j = l1 - 1; j >= 0; j--) {int1 = (int3 * (int(str1[j]) - 48) + int2) % 10;int2 = (int3 * (int(str1[j]) - 48) + int2) / 10;tempstr = char(int1 + 48) + tempstr;}if(int2 != 0) tempstr = char(int2 + 48) + tempstr; }str = ADD_INT(str, tempstr);}//去除结果中的前导0str.erase(0, str.find_first_not_of('0'));if(str.empty()) str = "0";if((sign == -1) && (str[0] != '0'))str = "-" + str;return str;}//⾼精度除法string DIVIDE_INT(string str1, string str2, int flag){//flag = 1时,返回商; flag = 0时,返回余数string quotient, residue; //定义商和余数int sign1 = 1, sign2 = 1;if(str2 == "0") { //判断除数是否为0quotient = "ERROR!";residue = "ERROR!";if(flag == 1) return quotient;else return residue;}if(str1 == "0") { //判断被除数是否为0quotient = "0";residue = "0";}if(str1[0] == '-') {str1 = str1.erase(0, 1);sign1 *= -1;sign2 = -1;}if(str2[0] == '-') {str2 = str2.erase(0, 1);sign1 *= -1;}int res = compare(str1, str2);if(res < 0) {quotient = "0";residue = str1;}else if(res == 0) {quotient = "1";residue = "0";string::size_type l1, l2;l1 = str1.size(); l2 = str2.size();string tempstr;tempstr.append(str1, 0, l2 - 1);//模拟⼿⼯除法for(int i = l2 - 1; i < l1; i++) {tempstr = tempstr + str1[i];for(char ch = '9'; ch >= '0'; ch --) { //试商string str;str = str + ch;if(compare(MULTIPLY_INT(str2, str), tempstr) <= 0) {quotient = quotient + ch;tempstr = MINUS_INT(tempstr, MULTIPLY_INT(str2, str)); break;}}}residue = tempstr;}//去除结果中的前导0quotient.erase(0, quotient.find_first_not_of('0'));if(quotient.empty()) quotient = "0";if((sign1 == -1) && (quotient[0] != '0'))quotient = "-" + quotient;if((sign2 == -1) && (residue[0] != '0'))residue = "-" + residue;if(flag == 1) return quotient;else return residue;}//⾼精度除法,返回商string DIV_INT(string str1, string str2){return DIVIDE_INT(str1, str2, 1);}//⾼精度除法,返回余数string MOD_INT(string str1, string str2){return DIVIDE_INT(str1, str2, 0);}int main(){char ch;string s1, s2, res;while(cin >> ch) {cin >> s1 >> s2;switch(ch) {case '+': res = ADD_INT(s1, s2); break; //⾼精度加法case '-': res = MINUS_INT(s1, s2); break; //⾼精度减法case '*': res = MULTIPLY_INT(s1, s2); break; //⾼精度乘法case '/': res = DIV_INT(s1, s2); break; //⾼精度除法, 返回商case 'm': res = MOD_INT(s1, s2); break; //⾼精度除法, 返回余数default : break;}cout << res << endl;}return(0);}。

pascal基础算法

pascal基础算法

一.简单题目1.高精度加法(1)数组法procedure add;var a,b,s:array[1..10000] of longint;i,j:longint;beginfor i:=1 to 10000 dobegins[i]:=s[i]+a[i]+b[i];if s[i]>9 thenbegins[i+1]:=s[i+1]+s[i] div 10;s[i]:=s[i] div 10;炸成林end;end;j:=10000;while (s[j]=0) and(j>1) do dec(j);for i:=j downto 1 do write(s[i]);end;(2)字符串法procedure add(s1,s2:string);var l1,l2:longint;i,j:longint;a:array[0..10000] of longint;s:string;x:longint;begins:='';l1:=length(s1); l2:=length(s2);if l1>l2 then for i:=1 to l1-l2 do s2:='0'+s2 else if l2>l1 then for i:=1 to l2-l1 do s1:='0'+s1;l1:=length(s1);for i:=l1 downto 1 dobeginx:=ord(s1[i])-ord('0')+ord(s2[i])-ord('0');a[l1-i]:=a[l1-i]+x;if a[l1-i]>9 thenbegina[l1-i+1]:=a[l1-i+1]+a[l1-i] div 10;a[l1-i]:=a[l1-i] mod 10;end;end;j:=l1;if a[j]=0 then dec(j);for i:=0 to j do s:=chr(a[i]+ord('0'))+s;writeln(s);end;2.高精度乘法(1)数组法procedure multiply;var i,j,k:longint;a,b,s:array[1..1001] of longint; beginfor j:=1 to 100 dobegink:=j;for i:=1 to 100 dobegins[k]:=s[k]+a[j]*b[i];s[k+1]:=s[k+1]+s[k] div 10;s[k]:=s[k] mod 10;inc(k);end;end;j:=1000;while (s[j]=0) and(j>1) do dec(j);for i:=j downto 1 do write(s[i]); end;(2)字符串法procedure multiply(s1,s2:string);var i,j,k:longint;l1,l2:longint;t,x:longint;s:string;a:array[0..1000] of longint;begins:='';l1:=length(s1); l2:=length(s2);if l1 >l2 thenbegint:=l1; l1:=l2; l2:=t;end;for i:=l1 downto 1 dobegink:=l1-i;for j:=l2 downto 1 dobeginx:=(ord(s1[i])-ord('0'))*(ord(s2[j])-ord('0'));a[k]:=a[k]+x;a[k+1]:=a[k+1]+a[k] div 10;a[k]:=a[k] mod 10;inc(k);end;end;if a[l1+l2-1]=0 then k:=l1+l2-2else k:=l1+l2-1;for i:=0 to k do s:=chr(a[i]+ord('0'))+s;writeln(s);end;3.混读字符串var n:longint;i:longint;name,mark:string;procedure inp;var s,s1:string;beginreadln(n);for i:=1 to n dobeginreadln(s);p:=pos(' ',s);s1:=copy(s,1,p-1);name:=s1;s1:=copy(s,p+1,length(s));mark:=s1;end;end;4. 进制转换(N进制-M进制)const st:string[16]=('0123456789ABCDEF'); var s:string;n:longint;a:array[1..100] of longint;procedure change; var i,j:longint;l:longint;beginreadln(n,m);readln(s);l:=length(s);for i:=1 to l dobeginfor j:=1 to 100 do a[j]:=a[j]*n;a[1]:=a[1]+pos(s[i],st)-1;for j:=2 to 100 dobegina[j]:=a[j]+a[j-1] div m;a[j-1]:=a[j-1] mod m;end;end;j:=100;while (a[j]=0) and(j>1) do dec(j); for i:=j downto 1 do write(a[i]); end;5.求两数的最大公约数function gcd(a,b:integer):integer; beginif b=0 then gcd:=aelse gcd:=gcd (b,a mod b);end;6.求两数的最小公倍数function lcm(a,b:integer):integer; beginif a< b then swap(a,B);lcm:=a;while lcm mod b >0 do inc(lcm,a); end;7. 素数(1).小规模判断function prime (n: integer): Boolean; var I: integer;beginfor I:=2 to trunc(sqrt(n)) doif n mod I=0 then beginprime:=false; exit;end;prime:=true;end;(2).判断longint范围内的数是否为素数(包含求50000以内的素数表):procedure getprime;vari,j:longint;p:array[1..50000] of boolean;beginfillchar(p,sizeof(p),true);p[1]:=false;i:=2;while i< 50000 do beginif p[i] then beginj:=i*2;while j< 50000 do beginp[j]:=false;inc(j,i);end;end;inc(i);end;l:=0;for i:=1 to 50000 doif p[i] then begininc(l);pr[l]:=i;end;end;{getprime(质数表)}function prime(x:longint):integer;var i:integer;beginprime:=false;for i:=1 to l doif pr[i] >=x then breakelse if x mod pr[i]=0 then exit;prime:=true;end;{prime(判断)}8.m的n次方var n,m:longint;procedure mn(i,s:longint);var t:longint; begint:=1;while i<>0 dobeginif i mod 2=1 then t:=t*s;s:=s*s;i:=i div 2;end;writeln(t);end;beginread(m,n);mn(n,m);end.9.简单排序(1).盲目排序procedure sort;beginfor i:=1 to n-1 dofor j:=i+1 to n doif a[j]<a[i] thenswap(a[i],a[j]);end;.(2). 选择排序:procedure sort;var i,j,k:integer;beginfor i:=1 to n-1 dobegink:=i;for j:=i+1 to n doif a[j]< a[k] then k:=j; {找出a[I]..a[n]中最小的数与a[I]作交换}if k< >i then begina[0]:=a[k];a[k]:=a[i];a[i]:=a[0];end;end;end;(3). 冒泡排序procedure sort;var i,j,k:integer;beginfor i:=n downto 1 dofor j:=1 to i-1 doif a[j] >a[i] then begina[0]:=a[i];a[i]:=a[j];a[j]:=a[0];end;end;(4).插入排序procedure sort;var x:longint;i,j:longint;beginfor i:=1 to n dobeginread(x);j:=1;while (a[j]<x) and (j>i) do inc(j);move(a[j],a[j+1],(i-j)*sizeof(a[j]));a[j]:=x;end;end;(5).下标排序法Procedure sort;BeginFor i:=1 to n do d[i]:=i;For i:=1 to n-1 doFor j:=i+1 to n doIf a[d[j]]<a[d[i] then swap(d[i],d[j]); End;10.排列与组合的生成(1).排列的生成:(1..n)procedure solve(dep:integer);vari:integer;beginif dep=n+1 then begin writeln(s);exit; end; for i:=1 to n doif not used[i] then begins:=s+chr(i+ord('0'));used[i]:=true;solve(dep+1);s:=copy(s,1,length(s)-1); used[i]:=false; end;end;(2).组合的生成(1..n中选取k个数的所有方案) procedure solve(dep,pre:integer);vari:integer;beginif dep=k+1 then begin writeln(s);exit; end;for i:=1 to n doif (not used[i]) and (i >pre) then begins:=s+chr(i+ord('0'));used[i]:=true;solve(dep+1,i);s:=copy(s,1,length(s)-1); used[i]:=false; end;end;11.折半查找function binsearch(k:keytype):integer;var low,hig,mid:integer;beginlow:=1;hig:=n;mid:=(low+hig) div 2;while (a[mid].key< >k) and (low< =hig) do beginif a[mid].key >k then hig:=mid-1else low:=mid+1;mid:=(low+hig) div 2;end;if low >hig then mid:=0;binsearch:=mid;end;二.Diggersun 复杂算法1.排序(1).归并排序{a为序列表,tmp为辅助数组} procedure merge(var a:listtype; p,q,r:integer); {将已排序好的子序列a[p..q]与a[q+1..r]合并为有序的tmp[p..r]}var I,j,t:integer;tmp:listtype;begint:=p;i:=p;j:=q+1;{t为tmp指针,I,j分别为左右子序列的指针}while (t< =r) do beginif (i< =q){左序列有剩余} and ((j >r) or (a[i]< =a[j])) {满足取左边序列当前元素的要求} then begintmp[t]:=a[i]; inc(i);endelse begintmp[t]:=a[j];inc(j);end;inc(t);end;for i:=p to r do a[i]:=tmp[i];end;{merge}procedure merge_sort(var a:listtype; p,r: integer); {合并排序a[p..r]}var q:integer;beginif p< >r then beginq:=(p+r-1) div 2;merge_sort (a,p,q);merge_sort (a,q+1,r);merge (a,p,q,r);end;end;{main}beginmerge_sort(a,1,n);end.(2).快速排序procedure qsort(s,t:longint);vari,j,x:longint;beginif t=s then exit;i:=s;j:=t;x:=data[s];while i<j dobeginwhile (i<j)and(data[j]>x)do dec(j);data[i]:=data[j];if i<j then inc(i);while (i<j)and(data[i]<x)do inc(i);data[j]:=data[i];if i<j then dec(j);end;data[i]:=x;if s<i-1 then qsort(s,i-1);if t>i+1 then qsort(i+1,t);end;2.树的遍历顺序转换A. 已知前序中序求后序procedure Solve(pre,mid:string);var i:integer;beginif (pre='') or (mid='') then exit;i:=pos(pre[1],mid);solve(copy(pre,2,i),copy(mid,1,i-1));solve(copy(pre,i+1,length(pre)-i),copy(mid,i+ 1,length(mid)-i));post:=post+pre[1]; {加上根,递归结束后post 即为后序遍历}end;B.已知中序后序求前序procedure Solve(mid,post:string);var i:integer;beginif (mid='') or (post='') then exit;i:=pos(post[length(post)],mid);pre:=pre+post[length(post)]; {加上根,递归结束后pre即为前序遍历}solve(copy(mid,1,I-1),copy(post,1,I-1)); solve(copy(mid,I+1,length(mid)-I),copy(post,I ,length(post)-i));end;C.已知前序后序求中序function ok(s1,s2:string):boolean;var i,l:integer; p:boolean;beginok:=true;l:=length(s1);for i:=1 to l do beginp:=false;for j:=1 to l doif s1[i]=s2[j] then p:=true;if not p then begin ok:=false;exit;end;end;end;procedure solve(pre,post:string);var i:integer;beginif (pre='') or (post='') then exit;i:=0;repeatinc(i);until ok(copy(pre,2,i),copy(post,1,i));solve(copy(pre,2,i),copy(post,1,i));midstr:=midstr+pre[1];solve(copy(pre,i+2,length(pre)-i-1),copy(post, i+1,length(post)-i-1));end;3.最短路径A.标号法求解单源点最短路径:vara:array[1..maxn,1..maxn] of integer;b:array[1..maxn] of integer; {b[i]指顶点i到源点的最短路径}mark:array[1..maxn] of boolean;procedure bhf;varbest,best_j:integer;beginfillchar(mark,sizeof(mark),false);mark[1]:=true; b[1]:=0;{1为源点}repeatbest:=0;for i:=1 to n doIf mark[i] then {对每一个已计算出最短路径的点}for j:=1 to n doif (not mark[j]) and (a[i,j] >0) thenif (best=0) or (b[i]+a[i,j]< best) then begin best:=b[i]+a[i,j]; best_j:=j;end;if best >0 then beginb[best_j]:=best;mark[best_j]:=true; end;until best=0;end;{bhf}(2).Dijkstra 算法:类似标号法,本质为贪心算法。

Pascal算法

Pascal算法

算法:
算法是程序的基础。

有了一个好的算法,再进行编码,把算法转换成任何一个程序设计语言所表示的程序。

算法就是解题步骤。

例题:求1——100这一百个相继整数的和S。

解法一:s=1+2+3+……+100 【需要100-1次加法】
解法二:s=(1+100)*50 【需要加法、乘法、除法各一次】不同的算法,对计算的工作量造成重大影响,还要考虑算法对精确度的影响。

程序质量的高低,主要取决于算法。

结构化程序特点:
1按功能相对独立原则划分若干模块。

2 单入口、单出口。

3 强调三种基本结构组成(顺序、选择、循环性)。

4 书写格式清晰。

5 不包含无限循环(即执行时间是有限的)
6 没有死语句(即程序中所有语句都能得到执行的机会)
设计结构化程序方法:
1 自顶向下
2 逐步细化。

3 按“功能单一”原则划分模块。

高精度运算1

高精度运算1

1.高精度加法
观察人工计算的方法:竖式加法 223 + 996 ----------9 3+6=9 11 2+9=11,当前位1,进位1 12 2+9+1=2,当前位2,进位1 1 进位的1 ----------1219
1.高精度加法
void jia(int a[],int b[]) //计算a=a+b { int i,k; if(a[0]<b[0])a[0]=b[0]; //确定加法最大位数 for(i=1;i<=a[0];i++) a[i]+=b[i]; //逐位相加 for(i=1;i<=a[0];i++) //处理进位 { a[i+1]+=a[i]/10; a[i]%=10; } if(a[a[0]+1]>0) a[0]++; //修正新的a的位数(a+b最多只能的一个进位) }
一.高精度数的存储,用字符串读入
void init(int a[]) 987654 { string s; cin>>s;//读入字符串s s1[0]…….....s1[n-1] a[0]=s.length(); //用a[0]计算字符串s的位数 987654 for(i=1;i<=a[0];i++) a[i]=s[a[0]-i]-'0'; a[n]…….....a[1] //将数串s转换为数组a,并倒序存储. }
2.判别整数数组m是否为回文数
bool check(int a[])//判别整数数组a是否为回文数 { for(i=1;i<=a[0]/2;i++) if(a[i]!=a[a[0]-i+1])return false; return true; }

高精度c语言乘法,C语言高精度乘法的实现方法

高精度c语言乘法,C语言高精度乘法的实现方法

⾼精度c语⾔乘法,C语⾔⾼精度乘法的实现⽅法对于要求很搞的C语⾔⾼精度乘法,相信很多⼈还没有⽤到过,应为在常规的应⽤中⼀般精度的乘法就可以满⾜我们的计算要求,今天⼀起来看看⾼精度乘法的实现⽅法吧。

/*⾼精度乘法输⼊:两⾏,每⾏表⽰⼀个⾮负整数(不超过10000位)输出:两数的乘积。

*/#include#include#include#include#define MAX 10001int bigchenfa(int *sum,int *a,int *b,int lsum,int la,int lb){int i,j,k ;memset(sum,0,sizeof(sum));lsum = 0 ;for(i=1 ; i<= la ; i ) /*⽤数组模拟运算*/for(j=1,lsum=i-1; j<= lb ; j )sum[ lsum] = b[j] * a[i] ;for(i=1 ; i<= lsum ; i )/*进位处理*/if (sum[i] >= 10){if ( sum[lsum] >= 10)lsum ;sum[i 1] = sum[i] / 10 ;sum[i] %= 10 ;}return lsum ;}int main(void){int a[MAX]={0},b[MAX]={0},sum[MAX*2]={0} ;int la=0,lb=0,lsum=0;int i,j ;char sa[MAX],sb[MAX] ;scanf(\"%s %s\",sa,sb);la = strlen(sa);lb = strlen(sb);for(i=1,j=la-1; i<= la ; i ,j--)a[i] = sa[j] - ’0’ ;for(i=1,j=lb-1; i<= lb ; i ,j--)b[i] = sb[j] - ’0’ ;lsum = bigchenfa(sum,a,b,lsum,la,lb) ; for(i=lsum ; i>= 1 ; i--) [Page]printf(\"%d\",sum[i]);printf(\" \");system(\"pause\");return 0 ;}本⽂来源:搜集于⽹络。

信息学奥赛课件 pascal10高精度计算

信息学奥赛课件 pascal10高精度计算

a[0]:=t; {把位数存入a[0]}
《PASCAL程序设计》第10课 — 高精度计算专题
②确定和的位数及进位处理 【参考程序段】
if a[0]>b[0] then c[0]:=a[0]
else c[0]:=b[0]; {比较两个数的位数,长的存入c[0]中}
y:=0;
{进位变量,赋初值为0}
for i:=1 to c[0] do
8
无符号64位
占字节数
6 4 8 10 8
有效位数
11..12 7..8 15..16 19..20 19..20
《PASCAL程序设计》第10课 — 高精度计算专题
高精度计算
➢ 在竞赛中应熟知各种数据类型的取值范围及占用空间的大小, 从而合理定义正确的数据类型。
➢ 当计算精度超出各种数据类型的范围时,就需要进行高精度 计算。
【单击此处查看完整程序】
《PASCAL程序设计》第10课 — 高精度计算专题
高精度减法
例3:输入两个长度小于200位的正整数N和M,输出N-M的差。
〖输入样例〗 〖输出样例〗
546
-326
872
【问题分析】
此题是一个高精度减法,我们要注意如下几个方面:
① 数据的接收及存储问题
② 负数的判断及处理
➢ 如果被减数的长度大于减数,则差必为正数。
872
【问题分析】
数据长度最大可能200位,可分析出这是高精度加法。
①数据的接收及存储问题
采用字符串输入,利用ord()函数把字符串转化为数值倒序存入数组中。
【倒序存入程序段】
t:=length(a1); {求字符串的长度}
for i:=t downto 1 do

高精度加减乘除法

高精度加减乘除法

借位处理
做减法运算时,要先判断是否需要借位,如果需要借位, 从上一位借过一个10,上一位的数减去1,处理完之后再相 减。 负数的处理 如果减数大于被减数,则交换A、B的值,并令负数标志 T=-1。当打印计算结果时,先判断 T 的值是否为-1,如果 T=-1,则在数值前面先输出一个负号。(怎样实现?)
分析eg: C[1=a[1]*b[1] C[2]=a[1]*b[2]+a[2]*b[1]+jw C[3]= a[3]*b[1]+a[2]*b[2]+jw C[4]=a[4]*b[1]+a[3]*b[2]+jw …… 观察: 1:a[i]*b[j]应该累加到:i+j-1位置 2:累加总结果为 C[i+j-1]= a[i]*b[j]+ C[i+j-1](原位置上的数 3:所以每次累加完后 1)带入下一位累加的进位为: c[i+j]+= C[i+j-1]/10 2)本位实际数: C[i+j-1]%= 10
+yu*10
1 3
实际被除数1 3 4
: C[I] 余数:yu

14 7 0
) /b
4
商=实际被除数 /b ? 商 C[i] = (a[i]
余=实际被除数 %b ? 余 yu =(a[i]
+yu*10 ) %b
高精度算法的实现——除法3
求多精度A÷多精度B的商和余数 ( 字符串比较
(奥通:P180-182)
:A>B)
数据的接收和存储 采用字符串输入的方式,设参与运算的两个数分别为A和B,利用字符串函数把字符串转化 为数值,将A、B中的每一位数字分别存储在A和B数组中,最低位在第一个单元中。 算法

高精度运算pascal

高精度运算pascal

高精度运算在实际中,我们常常需要进行一些很大的数的运算。

但是我们知道,计算机中整数的范围是有限的,这时候,我们就需要用到所谓的高精度运算。

通俗地讲,高精度运算就是用一个数组来表示整数,用模拟人解竖式的方法进行计算。

用一个整型数组表示一个数,其中数组的每一个元素表示数的一位。

第一个元素表示个位,第二个元素表示十位,以此类推。

另外还需要一个变量来存放这个数的长度,通常把这个长度存放在数组下标为0的元素中。

多余的元素要设成0。

高精度加法从个位开始,依次相加。

注意进位。

两个数相加,和的长度有可能大于其中任何一个数,因此要注意最后正确设置和的长度。

A[i]=a[i]+b[i],若a[i]>9 则dec(a[i],10), inc(a[I+1]);17532+2349=1988117532+ 2349--------------19881program gjdplus(input,output);varst:string;x,y:array[0..101]of integer;i,j,l1,l2:integer;beginassign(input,'gjdplus.in');reset(input);readln(st);fillchar(x,sizeof(x),0);fillchar(y,sizeof(y),0);l1:=length(st);for i:=l1 downto 1 dox[l1-i]:=ord(st[i])-ord('0');readln(st);l2:=length(st);for j:=l2 downto 1 doy[l2-j]:=ord(st[j])-ord('0');close(input);if l1<l2 then l1:=l2;for i:=0 to l1 dobeginif x[i]>=10 then begininc(x[i+1]);dec(x[i],10);end;end;while x[l1]<>0 do inc(l1);assign(output,'gjdplus.out');rewrite(output);for i:=l1-1 downto 0 dowrite(x[i]);close(output);end.高精度减法从个位开始,依次相减。

高精度运算--Pascal语言

高精度运算--Pascal语言

const max=100; Var s1,s2: string; a,b,c: array[1..max] of integer; i,top,k1,k2:integer; begin readln(s1); k1:=length(s1); readln(s2); k2:=length(s2); For i:=1 to k1 do a[k1-i+1] := ord(s1[i]) - ord('0') ; For i:=1 to k2 do b[k2-i+1] := ord(s2[i]) - ord('0') ; For i:=1 to max do c[i]:=a[i] - b[i]; For i:=1 to max do begin if c[i]<0 then begin c[i]:=c[i] + 10; c[i+1]:=c[i+1]-1 end; top:=max; while c[top]=0 do top:=top-1; for i:=top downto 1 do write(c[i]); end.
函数 copy(s, i, L)
s为string类型,i和L为整数类型,返回类型为string。 返回s串中,从第i个字符开始,长度为L的子串。
(3) 搜索子串位置
函数 pos(s1, s2)
s1和s2均为string类型,返回类型为整数。 s1若是s2的一个子串,则返回s1中第一个字符在s2中 的位置;若s1若不是s2的一个子串,则返回0。
7
逐位处理完毕后,就可以倒序输出了,但是为了避免输出左边没用的 零,要先确定第一个有效的数字在什么位置。这个可以用While循环从 高到低扫描,遇到第一个非零的数字,记录它的位置。

高精度加减乘除阶乘计算的算法及代码

高精度加减乘除阶乘计算的算法及代码

高精度计算
主要的方法是利用数组模拟计算比如:
高精度加法
12345678910111213 + 1111111111111111111
开两个数组存储:
a[]={3,1,2,1,1,1,0,1,9,8,7,6,5,4,3,2,1};
b[]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
两个数组分别把数值倒存,在一位一位的加,每位加后判断是否大于10,在进位(注:如果太大的数值,可以考虑4位一存哦.) 注意下面的a1,b1,c1 为数组的长度
四位一存:
高精度减法
--SepHiRoTH 18:59 2009年5月17日(CST) 高精度乘法
四位一计算:
更快的算法需要借助FFT(也有人喜欢用NTT) 实现nlogn 高精度除法
只提供程序段,未处理循环小数。

--Taophee 22:24 2011年8月20日
请看到这个问题的OIers注意并及时给出正确解法,最近忙于琐事,拜托了,这个网站很久无人管理了。

--SepHiRoTH 23:02 2011年7月30日(CST)
算法已改。

--Taophee 22:24 2011年8月20日
做一下循环小数,这需要加一段,既然做了就把它做好怎样?--SepHiRoTH 08:20 2011年8月21日(CST)
高精度阶乘
作为一种高精度乘法的扩展算法,实质为高精度乘低精度,算法如下:
--SepHiRoTH 18:59 2009年5月17日(CST)
高精度快速幂
主要用了二分的手段。

中间的乘法就看上面的吧。

--By Clarkok。

pascal竞赛中的高精度汇总

pascal竞赛中的高精度汇总

高精度数类型化
Type hp=array[0..200] of integer; Var n,m,sum:hp; Begin init//初始化高精度数 init(n); (即读入) init(m); add//高精度加法 add(sum,n,m); (即运算) print(sum); print//输出高精度数 End. (即输出)
模块化
参考程序
procedure init(var data:hp); var len,i:integer; s:string; begin readln(s); len:=length(s); data[0]:=len; for i:=1 to len do data[i]:=ord(s[len-i+1])-48; end; procedure print(ans:hp); var i:integer; begin for i:=ans[0] downto 1 do write(ans[i]); end; procedure mul(var ans:hp; a,b:hp); var i,j,len:integer; begin fillchar(ans,sizeof(ans),0); for i:=1 to a[0] do for j:=1 to b[0] do begin ans[i+j-1]:=ans[i+j-1]+a[i]*b[j]; ans[i+j]:=ans[i+j]+ans[i+j-1] div 10; ans[i+j-1]:=ans[i+j-1] mod 10; end; len:=a[0]+b[0]; if ans[len]>0 then ans[0]:=len else ans[0]:=len-1; end; 参考程序

Pascal教材需要掌握的程序段

Pascal教材需要掌握的程序段

Pascal教材重要的程序段P37 判断闰年P43 判断素数P52 P97 斐波那契数列的递归与非递归P47 最大公约数最小公倍数P53 1000!尾部有多少个连续的0P65 编程时常用fillchar对布尔型、整型数组赋初值执行fillchar(a,sizeof(a),0);当arrtype为1.real(其他实数类型差不多) 使得a中的元素全部成为0.02.integer(byte,word,longint,shortint都相同) 全部为03.boolean 全部为false4.char 全部为空串P67 杨辉三角形(A[I]的值,如何对齐) p201P69 数组中元素的插入和删除数据的前移和后移P70 矩阵的旋转顺时针旋转90°180°,逆时针旋转90°180°P72 P106 筛选法筛素数P73 P143 约瑟夫问题P74 奇数幻方P83 蛇形方阵P93 回文数P95 函数和过程的提前引用forward;把需要超前引用的过程或函数的首部放置在调用函数前面,并加上保留字forward P98 汉诺塔(当形参有多个,需要递归调用的时候,形参该怎样变化?递归终止的条件)P102 5-12P114 assign(intput,‘文件名’);Assign(output,‘文件名’);Reset(input);rewrite(output);whie not eof do……While not eoln do……ReadlnP161 水仙花数(分离数字)P165 进制间相互转化P170 0-1圈P173 高精度加减乘除法P179 二分查找(递归与非递归)P181 选择排序、基数排序简单排序(冒泡、插入、选择、归并、计数排序)有哪些顺序类型P38 case语句格式函数inc(i):i:=i+1;Dec(j);:j:=j-1;指针:单链表、双向链表、循环链表中插入或删除某一个元素,指针该怎么变化。

高精度四则运算

高精度四则运算

高精度四则运算
高精度除法: 1. 将被除数和除数从高位开始逐位相除,将每一位的结果保存在一个新的数组中。 2. 需要注意的是,如果被除数小于除数Байду номын сангаас则需要向高位借位。 3. 最后将得到的结果进行逆序输出即可。
需要注意的是,在进行高精度运算时,需要考虑到进位和借位的情况,以及结果的正负号 等特殊情况。
高精度四则运算
高精度减法: 1. 将被减数和减数从低位开始逐位相减,将每一位的结果保存在一个新的数组中。 2. 需要注意的是,如果减数大于被减数,则需要向高位借位。 3. 最后将得到的结果进行逆序输出即可。
高精度乘法: 1. 将两个大整数从低位开始逐位相乘,将每一位的结果保存在一个新的数组中。 2. 需要注意的是,相乘的结果可能会超过10,需要进行进位。 3. 最后将得到的结果进行逆序输出即可。
高精度四则运算
高精度四则运算是指在计算过程中保持数值的精度,避免因计算过程中的截断误差而导致 结果不准确的问题。在计算机中,通常使用字符串或数组来表示大整数,通过模拟手工计算 的过程进行运算。
高精度加法: 1. 将两个大整数从低位开始逐位相加,将每一位的结果保存在一个新的数组中。 2. 需要注意的是,如果相加的两个位数之和超过了9,则需要进位。 3. 最后将得到的结果进行逆序输出即可。

洛谷 高精度乘法

洛谷 高精度乘法

洛谷高精度乘法
高精度乘法是计算机科学中的一个概念,特别是在处理大整数运算时非常有用。

由于计算机内建的整数类型(如int, long等)有其大小限制,当进行超过这些限制的整数运算时,就需要使用高精度算法。

洛谷是一个面向程序员的在线判题系统,包含大量的算法练习题。

其中,高精度乘法就是一道常见的练习题。

在解决高精度乘法问题时,通常采用的策略是模拟手算乘法的过程。

具体步骤如下:
1.从右到左逐位处理被乘数和乘数。

2.对于被乘数的每一位,都将其与乘数相乘,并将结果加到对应的位置上。

注意,这里的乘法是普
通的整数乘法,结果可能超过一位。

3.如果相乘的结果超过一位,需要将进位加到下一位。

4.重复以上步骤,直到处理完被乘数的所有位。

这种方法的时间复杂度是O(n^2),其中n是被乘数和乘数的位数之和。

虽然这个算法的效率不是最高的,但对于大多数编程练习题来说,它已经足够快了。

如果你需要更高效的算法,可以考虑使用Karatsuba算法或者FFT(快速傅里叶变换)等方法,但这些方法实现起来相对复杂,且需要一定的数学背景。

在洛谷上,你可以找到很多高精度乘法的练习题,通过不断练习,你可以熟悉并掌握这种算法。

高精度除法——精选推荐

高精度除法——精选推荐

⾼精度除法我们平时做除法时,采⽤⽴竖式的⽅法计算:被除数从⾼位开始,和被除数对齐,诸位“试商”,“试商”后被除数减去“试商”的数的乘积,如下图所⽰:采⽤计算机做⾼精度除法时,模拟⽇常除法的步骤。

但计算机不可能做“试商”,这时,我们可以采⽤减法来模拟"试商"的过程。

算法的步骤如下:1、将除数移动和被除数对齐,位数不够时,补0,2、利⽤被除数减去除数,⼀直减到被除数⼩于除数,减的次数,就是“试商”的结果,每移动⼀次。

3、重复上述步骤,⼀直到被除数和除数的位数相等为⽌。

⾼精度算法的代码如下:#include <iostream>#include <cstring>using namespace std;const int N =1001;int aa[N],bb[N],cc[N]; //定义计算数和输出结果void inputNum(string ss,int a[]); //输⼊需要计算的数保存到数组void printArr(int a[]); //输出数组的元素void jian(int a[],int b[]);void jisuan(int a[],int b[],int c[]);void movei(int a[],int b[],int i);int compare (int a[],int b[]); //⽐较两个⾼精度数⼤⼩int main(){string s1 ="525353422";string s2 ="253532";inputNum(s1,aa);printArr(aa);inputNum(s2,bb);printArr(bb);if (compare(aa,bb) ==0) cout<<1<<endl;else if (compare(aa,bb)){jisuan(aa,bb,cc);}else if (compare(aa,bb)<0){jisuan(bb,aa,cc);}printArr(cc);printArr(aa);return0;}int compare (int a[],int b[]){int i;if (a[0]>b[0]) return1;if (a[0]<b[0]) return -1;for (i=a[0];i>0;i--){if (a[i]>b[i]) return1;if (a[i]<b[i]) return -1;}return0;}void movei(int a[],int b[],int j){for (int i=1;i<=a[0];i++){b[i+j-1] =a[i];}b[0] = a[0]+j-1;}void jisuan(int a[],int b[],int c[]){c[0] = a[0]-b[0]+1; //上的位数int temp[1001]; //临时数组,⽤于对除数进⾏移动for (int i=c[0];i>0;i--){memset(temp,0,sizeof(temp)); //全置为0movei(b,temp,i); //⾼位对齐while (compare(a,temp)>=0){c[i]++; //每次加1jian(a,temp);}}int m=c[0];while (c[0]>0 && c[m]==0) //处理商的位数{c[0]--;}}void jian(int a[],int b[]){for (int i=1;i<=a[0];i++){if (a[i]<b[i]){a[i+1]--;a[i]+=10;}a[i]-=b[i];}int i=a[0];while (a[i]==0){i--;}a[0]=i;}void inputNum(string ss,int a[]){int len = ss.length();a[0] = len;for (int i=0;i<len;i++){a[len-i] = ss[i] -48;//字符变成数字,并且倒序存储 }}void printArr(int a[]){for (int i=a[0];i>0;i--){cout<<a[i];}cout<<endl;}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
for i:=1 to len do {处理进位} begin a[i+1]:=a[i+1]+a[i] div 10; a[i]:=a[i] mod 10; end; m:=a[len+1];{处理最高进位} while m<>0 do begin {处理最高位的进位} inc(len); a[len]:=m mod 10; m:=m div 10; end;
const max=100; n=20; var a:array[1..max]of 0..9; i,j,k;x:integer; begin k:=1; a[k]:=1;{a=1} for i:=2 to n do{a*2*3….*n} begin x:=0;{进位初始化} for j:=1 do k do{a=a*i} begin x:=x+a[j]*i; a[j]:=x mod 10; x:=x div 10 end; while x>0 do {处理最高位的进位} begin k:=k+1; a[k]:=x mod 10; x:=x div 10 end end; writeln; for i:=k dowento 1 write(a[i]){输出a} end.
高精度运算乘法篇
高精度运算涉及到的问题:
1、数据的输入。字符串 2、数据的存储。数组
3、数据的运算:进位和借位。
4、结果的输出:小数点的位置、处理多于的0等。
整数i乘多精度数组a
设x为当前位乘积和进位 x:=x+a[j]*i; a[j]:=x mod 10; x:=x div 10
精确计算n的阶乘n!(7<n<50)
1.因为 50!<5050<10050=(102)50=10100 所以 50!可以用100个数组元素a[1],a[2],…,a[100]来存放, 一个数组元素存放一个数位上的数字。
X
j 100 99 98

3
2
1
a
……
a[1],a[2],…,a[max]的值可以是0到9的任意数字
2.用i表示阶乘中的整数,取值范围在1至50之间, j为数组变量 a的下标,取值范围在1至100之间,X存放来自低位的进位数。
三、高精度乘法
1、高精度乘单精度(整数),求a*b,a<=10200,b<=108 var i,len:integer; s:string; b,m:longint; a:array[1..250] of longint; begin readln(s); {读入被乘数a} readln(b); {读入乘数b} len:=length(s); for i:=1 to len do a[i]:=ord(s[len-i+1])-48; for i:=1 to len do {每项乘b} a[i]:=a[i]*b;
四、高精度除法
{高精度a除以单精度b} type data=array[0..300] of integer; var a,c:data; s1,s2:string; len,k:integer; i:integer; b,d:longint; procedure init; begin readln(s1); readln(b); fillchar(a,sizeof(a),0); len:=length(s1); for i:=1 to len do a[i]:=ord(s1[len-i+1])-48; end; procedure devide; {c:=a div b; d:= a mod b} var i:integer; begin fillchar(c,sizeof(c),0); d:=0; for i:=len downto 1 do begin d:=d*10+a[i]; c[i]:=d div b; d:=d mod b; end; while (len>=1) and (c[len]=0) do dec(len); for i:=len downto 2 do write(c[i]); writeln(c[1]); {writeln(d);} end; Begin init; devide; enlb,len:integer; s1,s2:string; m:longint; a,b,c:array[1..250] of integer; begin readln(s1); la:=length(s1); for i:=1 to la do a[i]:=ord(s1[la-i+1])-48; readln(s2); lb:=length(s2); for i:=1 to lb do b[i]:=ord(s2[lb-i+1])-48; for i:=1 to la do for j:=1 to lb do c[i+j-1]:=c[i+j-1]+a[i]*b[j]; len:=la+lb; for i:=1 to len do begin c[i+1]:=c[i+1]+c[i] div 10; c[i]:=c[i] mod 10; end; while c[len]=0 do dec(len); m:=c[len]; while m>0 do begin c[len]:=m mod 10;m:=m div 10;inc(len);end; for i:=len-1 downto 1 do write(c[i]) End.

for i:=len downto 1 do write(a[i]); end.{multiply}
if a[len+1]>0 then inc(len);
乘法运算a←a*b(a、b为numtype类型)
2、高精度乘高精度
1、积的位数为la+lb-1或者la+lb; 2、如果暂且不考虑进位关系,则ai*bj应该累加在积的第 j+i-1位上: x:= a[i]*b[j]+ x div 10+ c[i+j-1]; c[i+j-1] := x mod 10; 3、可以先乘、后处理进位
相关文档
最新文档