高精度算法

以下标程均为十进制,如改为10n进制可提高n倍速度。

建议不要使用operator对运算符进行重载,虽然用起来很方便,但是NOIP中不一定能用,速度也会慢一些。

高精度数大小比较

function a_dy_b(a,b:arr):boolean;
var i:integer;
begin
  i:=a[0];
  if a[0]<>b[0] then a_dy_b:=a[0]>b[0]
    else begin
      while (a[i]=b[i])and(i>0) do dec(i);
      a_dy_b:=a[i]>b[i];
    end;
end;

高精度+低精度

procedure add_h_l(a:arr;b:integer; var c:arr);
var i:integer;
begin
  a[1]:=a[1]+b;
  for i:=1 to a[0] do
    begin
      a[i+1]:=a[i+1]+a[i] div 10;
      a[i]:=a[i] mod 10;
    end;
  c:=a;c[0]:=max(c[0],19);
  while c[c[0]]=0 do dec(c[0]);
end;

高精度+高精度

procedure add_h_h(a,b:arr; var c:arr);
var i,j:integer;
begin
  fillchar(c,sizeof(c),0);
  if a[0]>b[0] then j:=a[0] else j:=b[0];
  for i:=1 to j do c[i]:=a[i]+b[i];
  for i:=1 to j do
    begin
      c[i+1]:=c[i+1]+c[i] div 10;
      c[i]:=c[i] mod 10;
    end;
  c[0]:=j+1;
  if c[c[0]]=0 then dec(c[0]);
end;

高精度-低精度(高精度数大于低精度数且低精度数小于1*109)

procedure jian_h_l(a:arr; b:longint; var c:arr);//arr为基类型是longint
var i,j:integer;
begin
  if a[0]>=10 then begin dec(a[10]);a[1]:=a[1]+1000000000;end
  else begin
    dec(a[a[0]]);
    j:=1;
    for i:=1 to a[0]-1 do  j:=j*10;
    a[1]:=a[1]+j;
  end;
  a[1]:=a[1]-b;
  for i:=1 to a[0]-1 do
    begin
      a[i+1]:=a[i+1]+a[i] div 10;  a[i]:=a[i] mod 10;
    end;
  while a[a[0]]=0 do dec(a[0]);
  c:=a;
end;

高精度-高精度

procedure jian_h_h(a,b:arr; var c:arr);//确保a>b
var i:integer;
begin
  for i:=a[0] downto 2 do begin dec(a[i]); a[i-1]:=a[i-1]+10;end;
  for i:=1 to a[0] do c[i]:=a[i]-b[i];
  for i:=1 to a[0]-1 do begin c[i+1]:=c[i+1]+c[i] div 10; c[i]:=c[i] mod 10;end;
  c[0]:=a[0];
  while c[c[0]]=0 do dec(c[0]);  if c[0]<1 then c[0]:=1;
end;

高精度*低精度

procedure cheng_h_l(a:arr; b:integer; var c:arr);
var i:integer;
begin
  fillchar(c,sizeof(c),0);
  for i:=1 to a[0] do c[i]:=a[i]*b;
  for i:=1 to a[0]+11 do begin c[i+1]:=c[i+1]+c[i] div 10; c[i]:=c[i] mod 10;end;
  c[0]:=a[0]+11;
  while c[c[0]]=0 do dec(c[0]);
end;

高精度*高精度

procedure cheng_h_h(a,b:arr; var c:arr);
var i,j:integer;
begin
  fillchar(c,sizeof(c),0);
  for i:=1 to a[0] do
    for j:=1 to b[0] do c[i+j-1]:=c[i+j-1]+a[i]*b[j];
  for i:=1 to a[0]+b[0] do begin c[i+1]:=c[i+1]+c[i] div 10; c[i]:=c[i] mod 10;end;
  c[0]:=a[0]+b[0];
  while c[c[0]]=0 do dec(c[0]);
end;

高精度/低精度

procedure chu_h_l(a:arr;b:integer; var c:arr; var d:integer);
var i:integer;
begin
  fillchar(c,sizeof(c),0);d:=0;
  for i:=a[0] downto 1 do begin d:=d*10+a[i]; c[i]:=d div b; d:=d mod b;end;
  c[0]:=a[0];
  while c[c[0]]=0 do dec(c[0]); if c[0]<1 then c[0]:=1;
end;

高精度/高精度(not ok)

用减法代替除法运算:不断比较A[1..n]与B[1..n]的大小,如果A[1..n]>=B[1..n]则商C[1..n]+1→C[1..n],然后就是一个减法过程:A[1..n]-B[1..n]→A[1..n]。由于简单的减法速度太慢,故必须进行优化。设置一个商的位置值J,当A[1..n]>B[1..n]时。B[1..n]左移→B[0..n],j:=j+1,即令B[1..n]增大10倍。这样就减少了减法的次数。当j>0且A[1..n]<B[0..n]时,B[0..n]右移→B[0..n],j:=j-1,即令B[1..n]缩小10倍。

function a_dy_b(a,b:arr):boolean;
var i:integer;
begin
  i:=a[0];
  if a[0]<>b[0] then a_dy_b:=a[0]>b[0]
  else begin
    while (a[i]=b[i])and(i>0) do dec(i);
    a_dy_b:=a[i]>b[i];
  end;
end;
procedure kuoda(a:arr;var b:arr);//将a扩大10倍
var i:integer;
begin
  fillchar(b,sizeof(b),0);
  b[0]:=a[0]+1;
  for i:=1 to a[0] do b[i+1]:=a[i];
end;
procedure suoxiao(a:arr;var b:arr);//将a缩小10倍
var i:integer;
begin
  fillchar(b,sizeof(b),0);
  for i:=2 to a[0] do b[i-1]:=a[i];
  b[0]:=a[0]-1;
end;
procedure jian_h_h(a,b:arr; var c:arr);//确保a>b
var i:integer;
begin
  for i:=a[0] downto 2 do begin dec(a[i]); a[i-1]:=a[i-1]+10;end;
  for i:=1 to a[0] do c[i]:=a[i]-b[i];
  for i:=1 to a[0]-1 do begin c[i+1]:=c[i+1]+c[i] div 10; c[i]:=c[i] mod 10;end;
  c[0]:=a[0];
  while c[c[0]]=0 do dec(c[0]);  if c[0]<1 then c[0]:=1;
end;
procedure chu_h_h(a,b:arr;var c,d:arr);//主要子程序,a:被除数,
var i,j:integer;    //b:除数;c:商;d:余数
begin
  c[0]:=a[0];  d:=b;//复制备份除数
  while a_dy_b(a,d) do//被除数仍然比除数大则循环
  begin
    b:=d;j:=1;
    while a_dy_b(a,b) do begin inc(j);   kuoda(b,b);end;    //扩大除数,最后一次循环后被除数已比除数小
    suoxiao(b,b);dec(j);//将除数缩小10倍以正好能除
    while a_dy_b(a,b) do begin inc(c[j]);  jian_h_h(a,b,a);end;//求得当前位的商
  end;
  d:=a;//a中保存的正好是小于除数的余数
  while c[c[0]]=0 do dec(c[0]);if c[0]<1 then c[0]:=1;
end;

高精度算法,布布扣,bubuko.com

时间: 2024-10-08 22:07:32

高精度算法的相关文章

c++加法高精度算法

c++高精度算法,对于新手来说还是一大挑战,只要克服它,你就开启了编程的新篇章,算法. 我发的这个代码并不是很好,占用内存很多而且运行时间很长(不超过1秒),但是很好理解,很适合新手 高精算法的本质就是把数组编程字符串,然后将字符串像竖式一样加起来: 1 #include <iostream> 2 #include <cmath> 3 #include <cstring> 4 using namespace std; 5 int main() 6 { 7 char a[

转载:C++之高精度算法

C++之高精度算法 注意:本文转载自http://blog.sina.com.cn/s/blog_4fdb102b010087ng.html,十分感谢原作者:忍者 前言:由于计算机运算是有模运算,数据范围的表示有一定限制,如整型int(C++中int 与long相同)表达范围是(-2^31~2^31-1),unsigned long(无符号整数)是(0~2^32-1),都约为几十亿.如果采用实数型,则能保存最大的double只能提供15~16位的有效数字,即只能精确表达数百万亿的数.因此,在计算

LeetCode43,一题让你学会高精度算法

本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode系列第22篇文章,今天讲的内容是高精度算法. 今天和大家讨论的算法是高精度,对应的LeetCode是第43题.题面其实没什么好说的,以字符串的形式给定两个数字,要求返回这两个数字的乘积.之所以是以字符串的形式给数字是因为这个数字可能会非常大,题目当中给定的范围是110位的数字.对于Python来说这不是问题,但是对于C++和Java等语言来说这么大的数字是无法以int类型存储的,所以必须要使用字符串来接收. 如果你

卡特兰数高精度算法

很多组合题都会用到卡特兰数,增长速度又很快,应该写个高精度尊敬一下~ 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define ML 549 5 using namespace std; 6 int kt[105][550]; 7 int len[105]; 8 int getlen(int ord) 9 { 10 int pos; 11 for(int i=ML;i>=0;i

【个人模板】高精度算法

一.求两个高精度正数的和差积 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 using namespace std; 6 const int MAXN=1000; 7 char s1[MAXN],s2[MAXN]; 8 int ed1,ed2,n1,n2; 9 int num1[MAXN]; 10 int num2[MAXN]; 11 int a

c++ 高精度算法

包括: 两个高精度正整数加法 两个高精度正整数乘法 两个高精度正整数减法 两个高精度正整数除法 两个高精度正整数求余 两个高精度正整数数求最大公约数 两个高精度正整数数求最小公倍数 1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 //清除前缀0,如果结果是空字符串则设为0 7 inline void clear(string& a){ 8 while(a.length()>0

[复习]高精度算法

今天又复习了一下高精度(高精度减.加.乘) 仍然用结构体来存储 数据结构: typedef struct HP{ int w[10001]             //储存数据,0下标储存有多少位 }HP: 注意:高精度为了进位需要反着存储 例如:原数             a     123   -int 高精度数          b       3 |2|1 –int[] 加法 先将最大的位数+1,然后按位相加,每次加完进位,最后删除前导0 减法 和高精度加法类似,相当于就是加上一个负数

算法笔记--高精度算法

高精度乘法: #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int M=1e3+5; char s1[M],s2[M]; int a[M],b[M],res[M]; int main() { gets(s1); gets(s2); int c=0; for(in

[高精度算法]高精度算法

高精度加法第三次学习...内容自己理解吧 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 using namespace std; 5 #define MAXLEN 110 6 int main(){ 7 char a1[MAXLEN],b1[MAXLEN];//输入的原始加数字符串 8 int a[MAXLEN],b[MAXLEN],c[MAXLEN],lena,lenb,lenc,x;//分