當前位置:首頁 » 操作系統 » 高精度演算法

高精度演算法

發布時間: 2022-01-20 13:03:20

1. 什麼是高精度

高精度演算法在一般的科學計算中,會經常算到小數點後幾百位或者更多,當然也可能是幾千億幾百億的大數字.
一般這類數字我們統稱為高精度數,高精度演算法是用計算機對於超大數據的一種模擬加,減,乘,除,乘方,階乘,開方等運算.
譬如一個很大的數字N >= 10^ 100, 很顯然這樣的數字無法在計算機中正常存儲.
於是, 我們想到了辦法,將這個數字拆開,拆成一位一位的 或者是四位四位的存儲到一個數組中, 用一個數組去表示一個數字.這樣這個數字就被稱謂是高精度數.
對於高精度數,也要像平常數一樣做加減乘除以及乘方的運算,於是就有了高精度演算法:
下面提供了Pascal的高精度加法, 高精度乘以單精度, 高精度乘以高精度的代碼, 其他版本請各位大牛添加進來吧!
Pascal代碼如下(非完整); k為預定進制,加大進制以提高速度。
Procere 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;
Procere 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;
Procere 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}

2. 求一個高精度的GPS演算法!

首先你要明白,你用GPS算出的點的數值和這個點的實際值是有誤差的,這個誤差的參數是多少,你必須知道,然後去做點校正。做好之後就是這個點的高精度數值,誤差一般在厘米級。你的演算法對不對我不好說,因為不清楚你的過程,但是知道這兩個點的准確數值之後,肯定對你有幫助。

3. 高精度運算

// 無符號整數的高精度加減乘除運算
#include < stdio.h >
#include < string.h >

const int DEV = 10000 ; //定義每個整數存放大整數中四位(104)
const int MAXN = 1000 ; //最大整數長度 MAXN×4

struct BIG_INT {
int bit [ MAXN ], cnt;
bool positive ;

BIG_INT (){ cnt=0; positive = true ; memset ( bit , 0 , sizeof ( bit ) ); }
//-------------------------------------------------輸入字元串,轉化為大整數的表示
void Input () {
char ts[1000] ;
scanf ( "%s", ts);
int i = 0 , j = 0 , pt = 0 ;
int len = strlen (ts);
for ( i = len-1 ; i >=0 ; i -= 4 )
{
int temp = 0 ;
for ( j = ( i-3 >= 0)?i-3:0 ; j <= i; j++ )
temp = temp * 10 + ts[j] - '0';
bit[ pt++ ] = temp ;
}
cnt = pt ;
while ( cnt > 0 && bit [ cnt - 1 ] == 0 ) cnt -- ;
}
//------------------------------------------------輸出大整數
void print () {
int i ;
if( cnt == 0 ) printf ( "%d\n", 0 );
else{
printf ( "%d", bit[cnt-1] );
for ( i=cnt-2 ; i >=0; i -- )
printf ( "%04d", bit );
printf ("\n") ;
}
}
//------------------------------------------------------加法
void add ( BIG_INT& fir, BIG_INT& sec ) {
cnt = 0 ;
int left = 0 ;
int pt = 0 ;
int temp = 0 ;
while ( pt < fir.cnt || pt < sec.cnt || left >0 ) {
temp = left ;
if ( pt < fir.cnt ) temp += fir.bit[pt] ;
if ( pt < sec.cnt ) temp += sec.bit[pt] ;
bit[ pt++ ] = temp%DEV ;
left = temp/DEV ;
}
cnt = pt;

}
// ----------------------------------減法,必須fir>sec !
void sub ( BIG_INT& fir, BIG_INT& sec ) {
cnt = 0 ;
int left = 0 ;
int pt = 0 ;
int temp = 0 ;
while ( pt < fir.cnt ){
temp = fir.bit[pt] - left ;
if ( pt < sec.cnt ) temp -= sec.bit[pt] ;
if( temp < 0){ temp += DEV; left = 1;}
else left = 0;
bit [pt++] = temp ;
}
cnt = pt ;
while ( bit[cnt-1] == 0 ) cnt-- ;
}
//---------------------------------乘法
void multiple ( BIG_INT& fir, BIG_INT& sec ) {
int i , j ;
cnt = 0 ;
memset ( bit , 0 ,sizeof ( bit ) );
int left = 0 ;
int temp = 0 ;
for ( i = 0 ; i < fir.cnt ; i++ )
{
left = 0 ;
for ( j = 0 ; j < sec.cnt ; j++ )
{
temp = left + fir.bit [ i ] * sec.bit [ j ] + bit [ i+j ];
bit [ i+j ] = temp % DEV ;
left = temp / DEV ;
}
while ( left > 0 )
{
temp = left + bit [ i+j ] ;
bit [ i+j ] = temp % DEV;
left = temp / DEV;
j++ ;
}
}
for ( i = MAXN - 1 ; i >= 0 ; i-- )
if ( bit [ i ] > 0) break;
cnt = i + 1 ;
}
// --------------------------------------比較fir與sec 大小
//--------------------------------------If ( fir < sec ) return true
bool smaller ( BIG_INT& fir, BIG_INT& sec){
while ( fir.cnt > 0 && fir.bit [ fir.cnt - 1 ] == 0 ) fir.cnt -- ;
while ( sec.cnt > 0 && sec.bit [ sec.cnt - 1 ] == 0 ) sec.cnt -- ;
if ( fir.cnt < sec.cnt ) return true;
else if ( fir.cnt > sec.cnt ) return false;
int i ;
for ( i = fir.cnt - 1 ; i >= 0 ; i -- ){
if ( fir.bit [ i ] < sec.bit [ i ] ) return true;
else if ( fir.bit [ i ] > sec.bit [ i ] ) return false;
}
return false;
}

// ----------------------------------------------返回 fir/sec 且fir = fir%sec
// -------------------------------------------- 供 devide 調用
int get_div ( BIG_INT& fir, BIG_INT& sec ){
int pt = 0 ;
BIG_INT tadd ;
while ( 1 ) {
if ( smaller ( fir, sec ) ) return pt ;
tadd.sub ( fir , sec );
fir = tadd ;
pt ++ ;
}
}
//-----------------------------------------------除法
void Devide ( BIG_INT& fir, BIG_INT& sec, BIG_INT& remd ) {
if( sec.cnt == 0 || ( sec.cnt == 1 && sec.bit [0] == 0 ) ) {
printf ( "Devide Error ! \n" ) ;
return ;
}
cnt = 0 ;
remd.cnt = 0;
memset ( bit , 0 , sizeof ( bit ) ) ;
memset ( remd.bit , 0 , sizeof ( remd.bit ) ) ;
int i , j ;
for ( i = fir.cnt - 1 ; i >= 0 ; i-- )
{
for ( j = remd.cnt - 1 ; j >= 0 ; j -- ) remd.bit [ j+1 ] = remd.bit [ j ] ;
remd.bit [ 0 ] = fir.bit [ i ] ;
remd.cnt ++ ;
int ret_n = get_div ( remd , sec ) ;
bit [ i ] = ret_n ;
}
for ( i = fir.cnt - 1 ; i >= 0 ; i-- )
if ( bit [ i ] > 0 ) break ;
cnt = i + 1 ;
}
};
//----------------------------------------------------調用參考
int main()
{
BIG_INT fir,sec,res;
while(1)
{
fir.Input();
sec.Input();
BIG_INT rem;
res.Devide ( fir , sec , rem );

res.print();
rem.print();
}
return 0;
}

4. 高精度計算 c語言

用位元組數組,並自定義運算方法。不過至少要慢100倍。

5. 高精度加法的基本演算法

以358934760892734899+38960302975237462為例:
1、計算結果的位數
358934760892734899共18位
38960302975237462共17位
故結果不會超過19位。
2、將要計算的數字分割成多段,按照順序排列(這里以0-32767作為每一存儲單位存儲的數的限制): 35 8934 7608 9273 4899 3 8960 3029 7523 7462 (為提高空間利用效率,可以一個存儲單位存儲多位數。)
3、將兩數相加。 35 8934 7608 9273 4899 3 8960 3029 7523 7462 和(不進位) 38 17894 10637 16796 12361 和(進位後) 39 7895 0638 6797 2361 4、輸出結果。
從高位到低位依次輸出。除最高位以外,其他低位上不足4位的要在前面補上0。

6. c語言高精度計算

不是我寫的,,幫你找到的。。
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include"stdlib.h"

voidmain()
{
intn=0,i=0,j=0,k=0,b=0;
chara[3][500]={0};
intn1=0,n2=0;
chars[500]={0};
intn3=0;
intc=0,c1=0;
inttemp=0;
charop;
charstr[1001]={0};
char*result;

scanf("%d",&n);
result=(char*)malloc(501*n);//根據輸入的n申請內存空間
*result='';

/*每次循環都要初始化*/
for(;i<n;i++)
{
//gets(str);
for(j=0;j<500;j++)
{
a[0][j]='';a[1][j]='';a[2][j]='';
s[j]='';
str[j]='';
str[1000-j]='';
}
c=0;c1=0;
k=0;
n1=0;n2=0;n3=0;

/*分離輸入的字元串*/
scanf("%s",&str);
for(j=0;str[j];j++)
{
if(str[j]!='+'&&str[j]!='-')
a[k][j-n1]=str[j];
else
{
op=str[j];
k=1;
n1=strlen(a[0])+1;
}
}//forj
n1-=2;
n2=strlen(a[1])-1;
n3=n1>n2?n1:n2;

/*計算加法*/
if(op=='+')
{
for(;n1>=0&&n2>=0;n1--,n2--,n3--)
{
temp=a[0][n1]+a[1][n2]-96;
temp+=c;
if(temp>=10)
{
s[n3]=temp%10+48;
c=1;
}
else
{
s[n3]=temp+48;
c=0;
}
}//for
while(n1>=0)
{
temp=a[0][n1]-48;
temp+=c;
if(temp==10)
{
s[n3]=48;
c=1;
}
else
{
s[n3]=temp+48;
c=0;
}
n1--;
n3--;
}//whilen1
while(n2>=0)
{
temp=a[1][n2]-48;
temp+=c;
if(temp==10)
{
s[n3]=48;
c=1;
}
else
{
s[n3]=temp+48;
c=0;
}
n2--;
n3--;
}//whilen2
if(c)
strcat(result,"1");
strcat(result,s);
strcat(result," ");
}//ifop

/*計算減法*/
else
{/*保證減數大於被減數
*如果被減數大於減數,則交換2數,並設置變數
*/
if(strcmp(a[0],a[1])<0)
{
//a[2]=a[0];a[0]=a[1];a[1]=a[2];
for(b=0;b<3;b++)
{
j=(b+2)%3;
for(k=0;k<=n2;k++)
a[j][k]=a[b][k];
}
n2=n1;n1=n3;
c1=1;//正為0,負為1
}

/*計算減法*/
for(;n2>=0;n1--,n2--,n3--)
{
temp=a[0][n1]-a[1][n2];
temp-=c;
if(temp>=0)
{
s[n3]=temp+48;
c=0;
}
else
{
s[n3]=temp+58;
c=1;
}
}//for
while(n1>=0)
{
temp=a[0][n1]-48;
temp-=c;
if(temp>=0)
{
s[n3]=temp+48;
c=0;
}
else
{
s[n3]=temp+58;
c=1;
}
n1--;
n3--;
}

if(c1)
strcat(result,"-");

/*消除減法結果高位的0*/
j=0;
while(s[j]==48)
j++;
strcat(result,s+j);
strcat(result," ");
}//elseop
}//fori
printf("%s",result);
getch()();
}

7. c++高精度運算

網路一下
「C++
高精度加法
、C++高精度減法、C++
高精度乘法
、C++高精度除法、C++高精度
冪運算
」至於mod。。mod就是好多個高精度減法(比如:12%5=12-5-5=2)

8. 高精度演算法

var a,b:string;
e,f,g:array[1..100] of integer;
w,c,d,h,q,i,j,k,n:integer;
begin
readln(a);
readln(b);
c:=length(a); 計算串長
d:=length(b); 計算串長

for i:=100 downto 1 do
val(a[c-100+i],f[i],h); 把a[c-100+i]這個字元轉換為數字保存在f[i]中,h沒有用,只是個標志
for i:=100 downto 1 do
val(b[d-100+i],g[i],q); 同上
for i:=100 downto 1 do
begin
e[i]:=f[i]+g[i]; 倒序相加
if e[i]>=10 then 大於10
begin
e[i]:=e[i]-10; 當前為-10
f[i-1]:=f[i-1]+1; 下一位+1
end; end;
i:=1;
while e[i]=0 do begin i:=i+1 ;end; 第一位是否為0,統計位數
for i:=i to 100 do
write(e[i]);writeln;
end.

9. 高精度演算法的C

模仿人類的豎式乘法 #include<stdio.h>#include<string.h>#defineMAXLEN200;//設置數的最大長度intmain(){inta[MAXLEN+10],b[MAXLEN+10],len1,len2,c[2*MAXLEN+10],i,j;charstr1[MAXLEN+10],str2[MAXLEN+10];for(i=0;i<MAXLEN+10;i++)a[i]=b[i]=0;//將a,b兩個數組都置為零for(i=0;i<2*MAXLEN+10;i++)c[i]=0;//將c置為零//scanf(%s%s,str1,str2);gets(str1);gets(str2);//以字元的形式讀入兩個乘數len1=strlen(str1);len2=strlen(str2);for(i=len1-1,j=0;i>=0;i--)//將字元型數轉換成數字,低位存在數組的低位(倒置)a[j++]=str1[i]-'0';字元型減去'0'的ASCIII碼值轉換為數字for(i=len2-1,j=0;i>=0;i--)b[j++]=str2[i]-'0';//同上for(i=0;i<len2;i++)//循環相乘,用第二個數的每一位去乘以第一個數,a的第i位乘以b的第j位之後存在c的第i+j位上for(j=0;j<len1;j++)c[i+j]+=b[i]*a[j];for(i=0;i<len1+len2+2;i++)//處理進位問題,如果大於10,則進位if(c[i]>=10){c[i+1]+=c[i]/10;c[i]%=10;}for(i=len1+len2+2;(c[i]==0)&&(i>=0);i--);//過濾掉高位的數字零,使之不輸出if(i>=0)for(;i>=0;i--)printf(%d,c[i]);elseprintf(0);printf( );return0;}

10. pascal的高精度演算法

高精度加法
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[i])-ord('0');{加數放入a數組}
write('Input addend:'); readln(n); lenb:=length(n);
for i:=1 to lenb do b[lenb-i+1]:=ord(n[i])-ord('0');{被加數放入b數組}
i:=1;
while (i<=lena) or(i<=lenb) do
begin
x := a[i] + b[i] + x div 10; {兩數相加,然後加前次進位}
c[i] := x mod 10; {保存第i位的值}
i := i + 1
end;
if x>=10 {處理最高進位}
then begin lenc:=i; c[i]:=1 end
else lenc:=i-1;
for i:=lenc downto 1 do write(c[i]); 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[i]){輸出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);
rite('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
begin
x:=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); {最高位的0不輸出}
for i:=lenc downto 1 do write(c[i]); 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[i])
else begin
for i←1 to st-1 do write(s[i]);
write('(');
for i←st to len do write(s[i]);
write(')');
end;{else}

熱點內容
編程鍵是什麼 發布:2024-09-20 07:52:47 瀏覽:651
學考密碼重置要求的證件是什麼 發布:2024-09-20 07:19:46 瀏覽:477
電腦主伺服器怎麼開機 發布:2024-09-20 07:19:07 瀏覽:728
2022款瑞虎升級哪些配置 發布:2024-09-20 06:59:07 瀏覽:264
資料庫與asp 發布:2024-09-20 06:55:25 瀏覽:727
python解釋編譯 發布:2024-09-20 06:52:57 瀏覽:648
舞蹈豐收腳本 發布:2024-09-20 06:36:26 瀏覽:595
linux進程埠號 發布:2024-09-20 06:36:11 瀏覽:80
派派怎麼改密碼忘了 發布:2024-09-20 06:25:49 瀏覽:780
linux虛擬地址物理地址 發布:2024-09-20 06:23:29 瀏覽:564