高精度

[b]高精度1[/b]


#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <set>
#include <queue>
#include <map>
using namespace std;
#define MAX 500

int Radix(char *toStr, char *fromStr)
{
int i = 0, j = 0;
int len;

while (fromStr[i] != '.' && fromStr[i] != '\0')
{
toStr[j++] = fromStr[i++];
}
len = i++;
while (fromStr[i] != '\0')
{
toStr[j++] = fromStr[i++];
}

return i - len - 1;
}

void IntAddition(char *augend, char *addend, char *sum)
{
int cAug[MAX] = {0};
int cAdd[MAX] = {0};
int cSum[MAX] = {0};
int lenAug = strlen(augend), lenAdd = strlen(addend);
int lenMin = lenAug < lenAdd ? lenAug : lenAdd;
int i;


for (i=0; i<lenAug; i++)
cAug[i] = augend[lenAug-1-i] - '0';
for (i=0; i<lenAdd; i++)
cAdd[i] = addend[lenAdd-1-i] - '0';

int carry = 0;
int s = 0;

for (i=0; i<lenMin; i++)
{
s = cAug[i] + cAdd[i] + carry;
cSum[i] = s % 10;
carry = s / 10;
}


while (i < lenAug)
{
s = cAug[i] + carry;
cSum[i] = s % 10;
carry = s / 10;
i++;
}

while (i < lenAdd)
{
s = cAdd[i] + carry;
cSum[i] = s % 10;
carry = s / 10;
i++;
}

if (carry > 0)
cSum[i++] = carry;


int j;
for (j=0; j<i; j++)
sum[j] = cSum[i-1-j] + '0';
sum[i] = '\0';
}


void IntMultiplication(char *multiplicand, char *multiplier, char *product)
{
int cD[MAX] = {0};
int cR[MAX] = {0};
int cP[MAX] = {0};
char tcP[MAX] = "";
int lenD = strlen(multiplicand), lenR = strlen(multiplier);
int i, j, k;


for (i=0; i<lenD; i++)
cD[i] = multiplicand[lenD-1-i] - '0';
for (i=0; i<lenR; i++)
cR[i] = multiplier[lenR-1-i] - '0';

int carry;
int mul = 0;

strcpy(product, "0");
for (i=0; i<lenR; i++)
{
carry = 0;
for (j=0; j<lenD; j++)
{
mul = cD[j] * cR[i] + carry;
cP[j] = mul % 10;
carry = mul / 10;
}
if (carry > 0)
cP[j++] = carry;

while (cP[j-1] == 0)
--j;


for (k=0; k<j; k++)
tcP[k] = cP[j-1-k] + '0';
for (j=0; j<i; j++)
tcP[k++] = '0';
tcP[k] = '\0';

IntAddition(product, tcP, product);
}
}


void FloatMultiplication(char *multiplicand, char *multiplier,char *product)
{
char cD[MAX] = {0};
char cR[MAX] = {0};
char cP[2*MAX] = {0};
int lenD, lenR, lenP;


lenD = Radix(cD, multiplicand);
lenR = Radix(cR, multiplier);
lenP = lenD + lenR;

IntMultiplication(cD, cR, cP);

int i = strlen(cP) - 1;
while (lenP > 0 && cP[i] == '0')
{
i--;
lenP--;
}
cP[i+2] = '\0';

while (lenP > 0 && i >= 0)
{
cP[i+1] = cP[i];
i--;
lenP--;
}
cP[i+1] = '.';

if (i == -1)
{
for (i=strlen(cP); i>0; --i)
cP[i+1+lenP] = cP[i];
for (i=0; i<lenP; ++i)
cP[i+2] = '0';
cP[1] = '.';
cP[0] = '0';
}

strcpy(product, cP);
}

int main()
{

char a[MAX];
int n;
int k;
int d=1;
int j,begin,end;
int i,t;
while(scanf("%s%d",a,&n)!=EOF)
{
k=0;
char ans[MAX*2]="1.0";
for(i=1;i<=n;i++)
{
FloatMultiplication(ans,a,ans);
}

for(i=0;ans[i]!='\0';i++)
{
if(ans[i]!='0'){begin=i;break;}
}
for(i=0;ans[i]!='\0';i++)end=i;
for(i=end;i>=0;i--)
{
if(ans[i]=='.')
{
end=i-1;
break;
}
if(ans[i]!='0')
{
end=i;
break;
}
}
for(i=begin;i<=end;i++)cout<<ans[i];
cout<<endl;
}
return 0;
}

/*power by gdut_chc*/


[b]高精度2[/b]

整数>>字符串(高精度常用):
string int_to_str(int a) //整数转为字符串

{

string result;

while(a)

{

result.insert(0,1,a%10+'0');

a /= 10;

}

return result;

}
字符串>>整数:

int str_to_int(string a)

{

int result = 0;

int s = 0;

while(s<a.size())

result = result*10 + a[s++]-'0';

return result;
}


加法:
string high_add(string a,string b)

{

a.insert(0,1,'0');

b.insert(0,1,'0');

if(a.size()>b.size())

b.insert(0,(int)a.size()-(int)b.size(),'0');

else if(a.size()<b.size())

a.insert(0,(int)b.size()-(int)a.size(),'0');

int ci = 0;

int N = a.size();

int x = 0;

for(int i = N-1;i>=0;i--)

{ x = a[i]-'0'+b[i]-'0'+ci;

if(x>=10)

{ ci = x/10; //顺序不能颠倒

x = x%10;

}

else

ci = 0;

a[i] = x + '0';

}

while(1)//输出控制

{ if(a[0]=='0'&&a.size()!=1)

{

a.erase (a.begin (),a.begin ()+1);

}

else break;

}

return a;

}

减法:(直接利用加法)

乘法:
string high_mut(string a,string b) //还利用了vector<int>,算法有待改进

{

vector<int> X; //转换到vector<int> 中

vector<int> Y;

int N = a.size();

X.assign(N,0);

int M = b.size();

Y.assign(M,0);

for(int i = 0;i<N;i++)

X[i] = a[i]-'0';

for(int i = 0;i<M;i++)

Y[i] = b[i]-'0';

vector<int> R;

R.assign(N+M,0);

//计算

string result;

int c = 0;

for(int i = M-1;i>=0;i--)

{

int site = N+M-1;

for(int j = N-1;j>=0;j--)

{

R[site-c] += X[j]*Y[i];

site--;

}

c++;

}

for(int i = N+M-1;i>=0;i--)

{

if(R[i]>=10)

{

R[i-1] += R[i]/10;

R[i] = R[i]%10;

}

result.insert(0,1,R[i]+'0');

}

//输出控制

while(1)

{

if(result[0]=='0'&&result.size()!=1)

result.erase (result.begin (),result.begin ()+1);

else break;

}

return result;

}


除法:
string high_div(string a,int b) //获得a/b的结果,类似整除,但是是用字符实现

{

string result;

int temp = a[0] - '0';

int s = 1;

go_on:

while(temp<b&&s<a.size())

{

temp = temp*10 + a[s++] - '0';

if(temp<b&&s<a.size())

result += '0';

}

result += temp/b + '0';

temp = temp%b;

if(s <a.size())

goto go_on;

else

{

while(result[0] == '0'&&result.size()>1)

result.erase(result.begin());

}

return result;

}

模除 :
int high_mod(string a,int b)

{

string result;

int temp = a[0] - '0';

int s = 1;

go_on:

while(temp<b&&s<a.size())

{

temp = temp*10 + a[s++] - '0';

if(temp<b&&s<a.size())

result += '0';

}

result += temp/b + '0';

temp = temp%b;

if(s <a.size())

goto go_on;

else

return temp;

}

阶乘:
string high_n(int m)

{

int n = m;

string sum = "1";

for(int i = n;i>=2;i--)

{

string temp = int_to_str(i); //调用转换函数

sum = high_mut(sum,temp);//高精度乘法

}

return sum;

}

进制转换:
string base_m(int n,int m)//把n转换为m(m<=36)进制数,最大数用Z表示

{

string temp; //保存n的进制数

string temp2;

int x = 0;

while(n >= m)

{

x = n%m;

n = n/m;

temp2 += '0'+x;

if(temp2[0] > '9')

temp2[0] = 'A'+x-10;

temp.insert(0,temp2);

temp2.clear();

}

temp2 += '0'+n;

if(temp2[0] > '9')

temp2[0] = 'A'+n-10;

temp.insert(0,temp2);

return temp;

}



[b]高精度3[/b]

JustForPlay 2004.3.8
// 无符号整数的高精度运算
#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;
}


[b]高精度4[/b]

基本方法

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;
begin
write('input s1:');readln(s1);
write('input s2:');readln(s2);
{————读入两个数s1,s2,都是字符串类型}
l:=length(s1);{求出s1的长度,也即s1的位数;有关字符串的知识。}
k1:=260;
for i:=l downto 1 do
begin
a[k1]:=ord(s1)-48;{将字符转成数值}
k1:=k1-1;
end;
k1:=k1+1;
{————以上将s1中的字符一位一位地转成数值并存在数组a中;低位在后(从第260位开始),高位在前(每存完一位,k1减1)}

对s2的转化过程和上面一模一样。

2、运算过程
在往下看之前,大家先列竖式计算35+86。
注意的问题:
(1)运算顺序:两个数靠右对齐;从低位向高位运算;先计算低位再计算高位;
(2)运算规则:同一位的两个数相加再加上从低位来的进位,成为该位的和;这个和去掉向高位的进位就成为该位的值;如上例:3+8+1=12,向前一位进1,本位的值是2;可借助MOD、DIV运算完成这一步;
(3)最后一位的进位:如果完成两个数的相加后,进位位值不为0,则应添加一位;
(4)如果两个加数位数不一样多,则按位数多的一个进行计算;
if k1>k2 then k:=k1 else k:=k2;
y:=0;
for i:=260 downto k do
begin
x:=a+b+y;
c:=x mod 10;
y:=x div 10;
end;
if y<>0 then begin k:=k-1;c[k]:=y; end;

3、结果的输出(这也是优化的一个重点)
按运算结果的实际位数输出
for i:=k to 260 do write(c);
writeln;


求两个数的加法
program sum;
var s,s1,s2:string;
a,b,c:array [1..260] of integer;
i,l,k1,k2:integer;
begin
write('input s1:');readln(s1);
write('input s2:');readln(s2);
l:=length(s1);
k1:=260;
for i:=l downto 1 do
begin
a[k1]:=ord(s1)-48;
k1:=k1-1;
end;
k1:=k1+1;

l:=length(s2);
k2:=260;
for i:=l downto 1 do
begin
b[k2]:=ord(s2)-48;
k2:=k2-1;
end;
k2:=k2+1;

if k1>k2 then k:=k2 else k:=k1;
y:=0;
for i:=260 downto k do
begin
x:=a+b+y;
c:=x mod 10;
y:=x div 10;
end;
if y<>0 then begin k:=k-1;c[k]:=y;
end;
for i:=k to 260 do write(c);
writeln;
end.

优化:

以上的方法的有明显的缺点:
(1)浪费空间:一个整型变量(-32768~32767)只存放一位(0~9);
(2)浪费时间:一次加减只处理一位;

针对以上问题,我们做如下优化:一个数组元素存放四位数;(integer的最大范围是32767,5位的话可能导致出界)。具体方法:
l:=length(s1);
k1:=260;
repeat
s:=copy(s1,l-3,4);
val(s,a[k1],code);
k1:=k1-1;
s1:=copy(s1,1,l-4);
l:=l-4;
until l<=0;
k1:=k1+1;
而因为这个改进,算法要相应改变:
(1)运算时:不再逢十进位,而是逢万进位(mod 10000; div 10000);
(2)输出时:最高位直接输出,其余各位,要判断是否足够4位,不足部分要补0;例如:1,23,2345这样三段的数,输出时,应该是100232345而不是1234567。

改进后的算法:
program sum;
var s1,s2:string;
a,b,c:array [1..260] of integer;
i,l,k1,k2,code:integer;

begin
write('input s1:');readln(s1);
write('input s2:');readln(s2);
l:=length(s1);
k1:=260;
repeat
s:=copy(s1,l-3,4);
val(s,a[k1],code);
k1:=k1-1;
s1:=copy(s1,1,l-4);
l:=l-4;
until l<=0;
k1:=k1+1;
l:=length(s2);
k2:=260;
repeat
s:=copy(s2,l-3,4);
val(s,b[k2],code);
k2:=k2-1;
s2:=copy(s2,1,l-4);
l:=l-4;
until l<=0;
k2:=k2+1;

if k1<k2 then k:=k1 else k:=k2;
y:=0;
for i:=260 downto k do
begin
x:=a+b+y;
c:=x mod 10000;
y:=x div 10000;
end;
if y<>0 then begin k:=k-1;c[k]:=y;end;

write(c[k]);
for i:=k+1 to 260 do
begin
----if c<1000 then write('0');
----if c<100 then write('0');
----if c<10 then write('0');
----write(c);
end;
writeln;
end.


高精度减法

1、和高精度加法相比,减法在差为负数时处理的细节更多一点:当被减数小于减数时,差为负数,差的绝对值是减数减去被减数;在程序实现上用一个变量来存储符号位,用另一个数组存差的绝对值。

2、算法流程:

(1)读入被减数S1,S2(字符串);

(2)置符号位:判断被减数是否大于减数:大则将符号位置为空;小则将符号位置为“-”,交换减数与被减数;

(3)被减数与减数处理成数值,放在数组中;

(4)运算:

A、取数;

B、判断是否需要借位;

C、减,将运算结果放到差数组相应位中;

D、判断是否运算完成:是,转5;不是,转A;

(5)打印结果:符号位,第1位,循环处理第2到最后一位;


3、细节:


▲如何判断被减数与减数的大小:字符串知识

(1)首先将两个字符串的位数补成一样(因为字符串的比较是从左边对齐的;两个字符串一样长才能真正地比较出大小):短的在左边补0

k1:=length(s1);

k2:=length(s2);

if k1>k2 then for i:=1 to k1-k2 do s2:='0'+s2

else for i:=1 to k2-k1 do s1:='0'+s1;

(2)接着比较大小:直接比较字符串大小

fh:='';

if s1<s2 then begin fh:='-';s:=s1; s1:=s2; s2:=s; end;

{————s1存被减数,符号存符号}

▲将字符串处理成数值:

l:=length(s1);{求出s1的长度,也即s1的位数;有关字符串的知识。}
k1:=260;
for i:=l downto 1 do
begin
a[k1]:=ord(s1)-48;{将字符转成数值}
k1:=k1-1;
end;
k1:=k1+1;


▲打印结果:
例:差:第一位是12,第二位是234,第三位是1234,最后一位:3。它的实际数值是12023412340003。
从上例可以看出:打印时,从第二位开始,因为每一段都代表4位,不足4位的要补足0。

write(fh,c[k]);{k是差的第1位;}
for i:=k+1 to 260 do
begin
if c<1000 then write('0');
if c<100 then write('0');
if c<10 then write('0');
write(c);
end;


高精度乘法和阶乘


一、高精度乘法基本思想和加法一样。其基本流程如下:


①读入被乘数s1,乘数s2

②把s1、s2分成4位一段,转成数值存在数组a,b中;记下a,b的长度k1,k2;

③i赋为b中的最低位;

④从b中取出第i位与a相乘,累加到另一数组c中;(注意:累加时错开的位数应是多少位?)

⑤i:=i-1;检测i值:小于k2则转⑥,否则转④

⑥打印结果


例:程序下载


program chengfa;

const n=100;

type ar=array [1..n] of integer;

var a,b:ar; k1,k2,k:integer;

c:array [1..200] of integer;

s1,s2:string;

procedure fenge(s:string;var d:ar; var kk:integer);

var ss:string;

i,code:integer;

begin

i:=length(s);

kk:=n;

repeat

ss:=copy(s,i-3,4);

val(ss,d[kk],code);

kk:=kk-1;

s:=copy(s,1,i-4);

i:=i-4;

until i<0;

kk:=kk+1;

end;

procedure daying;

var i:integer;

begin

write(c[k]);

for i:=k+1 to 2*n do begin

if c<1000 then write('0');

if c<100 then write('0');

if c<10 then write('0');

write(c);

end;

writeln;

end;

begin

init;

jisuan;

daying;

end.


二、求N!当N稍微大一点时结果就很大了(如n=10时N!=3628800;n=20时N!=2432902008176640000);因此,求阶乘通常都要用到高精度算法。基本过程和乘法一样,只是多了控制乘法次数的一层循环。


var

a,b,c:array[1..1000] of integer;

i,j,l,m,k1,k2,x,y,z,w,n,t:integer;


procedure chengfa; {高精度乘法}

begin

for l:=1 to k1 do

for m:=1 to k2 do

begin

x:=a[l]*b[m];

y:=x div 10;

z:=x mod 10;

w:=l+m-1;

c[w]:=c[w]+z;

c[w+1]:=c[w+1]+y+c[w] div 10;

c[w]:=c[w]mod 10

end;

k1:=k1+k2; {位数为K1、K2的两数相乘最大只有K1+K2位}

if c[k1]=0 then k1:=k1-1; {如果最高位为0则位数减少一位}

for t:=1 to k1 do a[t]:=c[t]; {把一次高精度相乘的结果放到A数组中,以便下次相乘}

for t:=1 to k1 do c[t]:=0; {同时把数组C清空,以便下次相乘,因为每调用此过程一次都是一次 全新的高精度乘法,所以数组C必须清空}

end;


procedure zhuanhuan; {把I每一位分解开分别赋值给数组B的每一个元素}

begin

if i>=100 then

begin

k2:=3;

b[3]:=i div 100;

b[2]:=(i-b[3]*100) div 10;

b[1]:=i-b[3]*100-b[2]*10

end

else

if i>=10

then

begin

k2:=2;

b[2]:=i div 10;

b[1]:=i-b[2]*10

end

else

begin

k2:=1;

b[1]:=i

end;

end;


begin

writeln('input:');

readln(n);

a[1]:=1; {最后结果放在数组A中}

k1:=1;

for i:=2 to n do

begin

zhuanhuan;

chengfa;

end;

writeln(n:2,'!= ');

for i:=k1 downto 1 do write(a)

end.


高精度除法(1)


{

author : tenshi

date : 2002-03-10

problem : high precision --- divide

algorithm : simple

input : two lines,

1st line : a positive highprecision number

2nd line : a positive low precicion number

output : times & rest of the two numbers

}

program highprecision3_multiply1;

const

fn_inp='hp5.inp';

fn_out='hp5.out';

maxlen=100; { max length of the number }

type

hp=record

len:integer; { length of the number }

s:array[1..maxlen] of integer

{ s[1] is the lowest position

s[len] is the highest position }

end;

var

x,y:hp;

z,w:integer;


procedure printhp(const p:hp);

var i:integer;

begin

for i:=p.len downto 1 do write(p.s);

end;


procedure init;

var

st:string;

i:integer;

begin

assign(input,fn_inp);

reset(input);

readln(st);

x.len:=length(st);

for i:=1 to x.len do { change string to hp }

x.s:=ord(st[x.len+1-i])-ord('0');

readln(z);

close(input);

end;


procedure divide(a:hp;b:integer;var c:hp;var d:integer);

{ c:=a div b ; d:=a mod b }

var i,len:integer;

begin

fillchar(c,sizeof(c),0);

len:=a.len;

d:=0;

for i:=len downto 1 do { from high to low }

begin

d:=d*10+a.s;

c.s:=d div b;

d:=d mod b;

end;

while(len>1) and (c.s[len]=0) do dec(len);

c.len:=len;

end;


procedure main;

begin

divide(x,z,y,w);

end;


procedure out;

begin

assign(output,fn_out);

rewrite(output);

printhp(y);

writeln;

writeln(w);

close(output);

end;


begin

init;

main;

out;

end.


高精度除法(2)


{

author : tenshi

date : 2002-03-10

problem : high precision --- divide

algorithm : simple

input : two lines, each line a positive highprecision number

output : quotient & modulus of the two highprecision numbers

}

program highprecision4_multiply2;

const

fn_inp='hp6.inp';

fn_out='hp6.out';

maxlen=100; { max length of the number }

type

hp=record

len:integer; { length of the number }

s:array[1..maxlen] of integer

{ s[1] is the lowest position

s[len] is the highest position }

end;

var

x:array[1..2] of hp;

y,w:hp; { x:input ; y:output }


procedure printhp(const p:hp);

var i:integer;

begin

for i:=p.len downto 1 do write(p.s);

end;


procedure init;

var

st:string;

j,i:integer;

begin

assign(input,fn_inp);

reset(input);

for j:=1 to 2 do

begin

readln(st);

x[j].len:=length(st);

for i:=1 to x[j].len do { change string to hp }

x[j].s:=ord(st[x[j].len+1-i])-ord('0');

end;

close(input);

end;


procedure subtract(a,b:hp;var c:hp); { c:=a-b, suppose a>=b }

var i,len:integer;

begin

fillchar(c,sizeof(c),0);

if a.len>b.len then len:=a.len { get the bigger length of a,b }

else len:=b.len;

for i:=1 to len do { subtract from low to high }

begin

inc(c.s,a.s-b.s);

if c.s<0 then

begin

inc(c.s,10);

dec(c.s[i+1]); { add 1 to a higher position }

end;

end;

while(len>1) and (c.s[len]=0) do dec(len);

c.len:=len;

end;


function compare(const a,b:hp):integer;

{

1 if a>b

0 if a=b

-1 if a<b

}

var len:integer;

begin

if a.len>b.len then len:=a.len { get the bigger length of a,b }

else len:=b.len;

while(len>0) and (a.s[len]=b.s[len]) do dec(len);

{ find a position which have a different digit }

if len=0 then compare:=0 { no difference }

else compare:=a.s[len]-b.s[len];

end;


procedure multiply10(var a:hp); { a:=a*10 }

var i:integer;

begin

for i:=a.len downto 1 do

a.s[i+1]:=a.s;

a.s[1]:=0;

inc(a.len);

while(a.len>1) and (a.s[a.len]=0) do dec(a.len);

end;


procedure divide(a,b:hp;var c,d:hp); { c:=a div b ; d:=a mod b }

var i,j,len:integer;

begin

fillchar(c,sizeof(c),0);

len:=a.len;

fillchar(d,sizeof(d),0);

d.len:=1;

for i:=len downto 1 do

begin

multiply10(d);

d.s[1]:=a.s; { d:=d*10+a.s }

{ c.s:=d div b ; d:=d mod b; }

{ while(d>=b) do begin d:=d-b;inc(c.s) end }

while(compare(d,b)>=0) do

begin

subtract(d,b,d);

inc(c.s);

end;

end;

while(len>1)and(c.s[len]=0) do dec(len);

c.len:=len;

end;


procedure main;

begin

divide(x[1],x[2],y,w);

end;


procedure out;

begin

assign(output,fn_out);

rewrite(output);

printhp(y);

writeln;

printhp(w);

writeln;

close(output);

end;


begin

init;

main;

out;

end.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值