高精度算法(引用)

来源:互联网 发布:国境之南太阳以西知乎 编辑:程序博客网 时间:2024/05/17 07:05

高精度算法(引用)

  在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字.
  一般这类数字我们统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算.
  譬如一个很大的数字N >= 10^ 100, 很显然这样的数字无法在计算机中正常存储.
  于是, 我们想到了办法,将这个数字拆开,拆成一位一位的 或者是四位四位的存储到一个数组中, 用一个数组去表示一个数字.这样这个数字就被称谓是高精度数.
  对于高精度数,也要像平常数一样做加减乘除以及乘方的运算,于是就有了高精度算法:
  下面提供了Pascal的高精度加法, 高精度乘以单精度, 高精度乘以高精度的代码, 其他版本请各位大牛添加进来吧!
  Pascal代码如下(非完整); k为预定进制,加大进制以提高速度。
  Procedure HPule(a, b: Arr; Var c:Arr); //高精度加法
  Var
  i: Integer;
  Begin
  FillChar(c, SizeOf(c), 0);
  For i:= 1 To Maxn-1 Do Begin
  c[i]:= c[i] + a[i] + b[i];
  c[i + 1] := c[i] Div k;
  c[i] := c[i] Mod k;
  End;
  End;
  Procedure HPule(a: Arr; b:Integer; Var c:Arr); //高精度乘以单精度
  Var
  i: Integer;
  Begin
  FillChar(c, SizeOf(c), 0);
  For i:= 1 To Maxn-1 Do Begin
  c[i] := c[i] + a[i] * b;
  c[i+1]:= c[i] Div k;
  c[i]:= c[i] Mod k
  End;
  End;
  Procedure HPule(a, b: Arr; ; Var c:Arr); //高精度乘以高精度
  Var
  i, j: Integer;
  Begin
  FillChar(c, SizeOf(c), 0);
  For i:= 1 To Maxn Do
  For j := 1 To Maxn Begin
  c[i+j-1] := c[i+j-1] + a[i] * b[j];
  c[i+j]:= c[i+j-1] Div k;
  c[i+j-1]:= c[i+j-1] Mod k
  End;
  End;
  Ps:为了防止百度错误识别, 过程中有不少符号是全角状态输入.
  高精度加法
  var
  a,b,c:array[1..201] of 0..9;
  n:string;
  lena,lenb,lenc,i,x:integer;
  begin
  write('Input augend:'); readln(n);lena:=length(n);
  for i:=1 to lena do a[lena-i+1]:=ord(n)-ord('0');{加数放入a数组}
  write('Input addend:'); readln(n); lenb:=length(n);
  for i:=1 to lenb do b[lenb-i+1]:=ord(n)-ord('0');{被加数放入b数组}
  i:=1;
  while (i<=lena) or(i<=lenb) do
  begin
  x := a + b + x div 10; {两数相加,然后加前次进位}
  c := x mod 10; {保存第i位的值}
  i := i + 1
  end;
  if x>=10 {处理最高进位}
  then begin lenc:=i; c:=1 end
  else lenc:=i-1;
  for i:=lenc downto 1 do write(c); writeln {输出结果}
  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){输出a}
  end.
  高精度乘法(高对高)
  var a,b,c:array[1..200] of 0..9;
  n1,n2:string; lena,lenb,lenc,i,j,x:integer;
  begin
  write('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)-ord('0');
  for i:=1 to lenb do b[lenb-i+1]:=ord(n2)-ord('0');
  for i:=1 to lena do
  begin
  x:=0;
  for j:=1 to lenb do{对乘数的每一位进行处理}
  begin
  x := a*b[j]+x div 10+c;{当前乘积+上次乘积进位+原数}
  c:=x mod 10;
  end;
  c:= x div 10;{进位}
  end;
  lenc:=i+j;
  while (c[lenc]=0) and (lenc>1) do dec(lenc); {最高位的0不输出}
  for i:=lenc downto 1 do write(c); writeln
  end.
  高精度除法
  fillchar(s,sizeof(s),0);{小数部分初始化}
  fillchar(posi,sizeof(posi),0); {小数值的位序列初始化}
  len←0;st←0; {小数部分的指针和循环节的首指针初始化}
  read(x,y);{读被除数和除数}
  write(x div y);{输出整数部分}
  x←x mod y;{计算x除以y的余数}
  if x=0 then exit;{若x除尽y,则成功退出}
  while len<limit do{若小数位未达到上限,则循环}
  begin
  inc(len);posi[x]←len;{记下当前位小数,计算下一位小数和余数}
  x←x*10; s[len]←x div y;x←x mod y;
  if posi[x]<>0 {若下一位余数先前出现过,则先前出现的位置为循环节的开始}
  then begin st←posi[x]; break;end;{then}
  if x=0 then break; {若除尽,则成功退出}
  end;{while}
  if len=0
  then begin writeln;exit;end;{若小数部分的位数为0,则成功退出;否则输出小数点}
  write('.');
  if st=0 {若无循环节,则输出小数部分,否则输出循环节前的小数和循环节}
  then for i←1 to len do write(s)
  else begin
  for i←1 to st-1 do write(s);
  write('(');
  for i←st to len do write(s);
  write(')');
  end;{else}

原创粉丝点击