#include <iostream>
using namespace std;
const long MAXN = 100000;
inline long& len(long* a)
{
return a[MAXN-1];
}
void copy(long* to, long* scr)
{
len(to) = len(scr);
memcpy(to,scr,sizeof(long)*len(to));
}
void change(char* s,long l, long* a)//l是s的长度
{
long i,j(0),cnt(0),k;
if (l <= 4)
{
for (i=0; i<l; i++)
j = j*10 + s[i] - '0';
a[len(a)++] = j;
}
else
{
for (i=l-4; i<l; i++)
j = j*10 + s[i] - '0';
a[len(a)++] = j;
s[l-4] = '/0'; //截断刚才的4位
change(s, l-4, a);
}
}
void cheng(long* a, long* b, long* c)
{
long i,j;
len(c) = len(a) + len(b);
memset(c,0,sizeof(long)*len(c));
for (i=0; i<len(a); i++)
for (j=0; j<len(b); j++)
{
c[i+j] += a[i] * b[j];
c[i+j+1] += c[i+j] / 10000;
c[i+j] %= 10000;
}
while(len(c) > 1 && c[len(c)-1] == 0) len(c)--;
}
void print(long* a)
{
long i;
printf("%ld",a[len(a)-1]);
for (i=len(a)-2; i>=0; i--)
printf("%04ld",a[i]);
printf("/n");
}
int main(void)
{
long i,n,a[MAXN],b[MAXN],c[MAXN];
char s[10000];
while(scanf("%s",s) == 1)
{
len(a) = 0;//需要这样
change(s,strlen(s),a);
while(len(a) > 1 && a[len(a)-1] == 0) len(a)--; //去前导零
scanf("%s",s); len(b) = 0;
change(s,strlen(s),b);
cheng(a,b,c);
print(c);
}
return 0;
}
o
下面是一个类似于strlen()的函数,在这个高精度计算的过程中都要用到~
o
const long MAXN = 100000;//一个很大的数
o
inline long& len(long* a)
o
{
o
return a[MAXN-1];
o
}
o
为什么返回一个引用,是为了可以存在如下语句len(a) = 0; len(a)++;等等.
o
其实本质上写这个函数的目的是少用一个len变量,一个数组就要对应一个len变量,要么用struct,要么用很多len变量.这两者都挺麻烦的,所以就想到搞了这么一个函数.
o
当然,绝对不是说不能用struct,不能用别的变量记录长度.
o
void change(char* s, long* a)
o
{
o
long i,j;
o
len(a) = strlen(s);
o
memset(a,0,sizeof(long)*len(a));
o
for (i=0,j=len(a)-1; i<len(a); i++,j--)
o
a[j] = s[i] - '0';
o
while(len(a) > 1 && a[len(a)-1] == 0)
len(a)--;(
把高位的0出去?我的标注)
o
}
o
将字符串s转换成long数组a,红色的字可以将s串倒置存入a数组
o
void print(long* a)
o
{
o
long i;
o
for (i=len(a)-1; i>=0; i--)
o
printf("%ld",a[i]);
o
printf("/n");
o
}
o
print()函数用于输出一个a数组,也就是打印一个高精度数,注意要反过来打印~
o
void copy(long* to, long* scr)
o
{
o
len(to) = len(scr);
o
memcpy(to,scr,sizeof(long)*len(to));
o
}
o
o
void jia(long* a, long* b, long* c)//实现c = a + b
o
{
o
long i,j = max(len(a), len(b));
o
o
if (c == a)//
为了实现a = a + b
o
{
o
for (i=len(c); i<len(b)+1; i++)//
必要的清零
o
c[i] = 0;
o
len(c) = j + 1;
o
}
o
else if (c == b)//
为了实现
b = a + b
{
o
jia(b,a,c);//
J
return;//!!!!!!
}
用于将scr(源)复制到to(目标)中.
o
else
o
{
o
memset(c,0,sizeof(long)*(j+1));
o
copy(c,a);
o
len(c) = j + 1;
o
}
o
o
for (i=0; i<len(b); i++)
o
{
o
c[i] += b[i];
o
c[i+1] += c[i] / 10;
o
c[i] %= 10;
o
}
o
for (i=len(b); i<j; i++)//
处理没有处理到的进位问题
o
{
o
c[i+1] += c[i] / 10;
o
c[i] %= 10;
o
}
o
o
while(len(c) > 1 && c[len(c)-1] == 0) len(c)--;
o
}
o
c[i+1] += c[i] / 10;
o
c[i] %= 10;
o
这两句解决了进位的问题,而且对进不进都适用.更一般的,如果把其中的10换成n的话,就是一个n进制的加法(还需要改一下print函数)对后面的减法,乘法同样适用.
o
while(len(c) > 1 && c[len(c)-1] == 0) len(c)--;
o
这句话的作用是去除前导零(如果是0除外)
o
这里为了方便起见,把a赋值给c,然后在c的基础上加上b.
o
注意,这样操作,不管c == a,还是c != a,都是正确的.想想是为什么?~
o
还有,当c == b时,用了递归调用,其实也很好理解~
o
下面是减法的代码:
o
void jian(long* a, long* b, long* c) //c = a - b, 需要a >= b
o
{
o
long i;
o
len(c) = len(a); //
因为规定了a >= b
o
if (c != a) copy(c,a);
o
o
for (i=0; i<len(c); i++)
o
{
o
c[i] -= b[i];
o
if (c[i] < 0)
o
{
o
c[i] += 10;
o
c[i+1] -= 1;
o
}
o
}
o
while(len(c) > 1 && c[len(c)-1] == 0) len(c)--;
o
乘法代码:
o
void cheng(long* a, long* b, long* c)// c = a * b
o
{
o
long i,j;
o
len(c) = len(a) + len(b);
o
memset(c,0,sizeof(long)*len(c));
o
o
for (i=0; i<len(a); i++)
o
for (j=0; j<len(b); j++)
o
{
o
c[i+j] += a[i] * b[j];
o
c[i+j+1] += c[i+j] / 10;
o
c[i+j] %= 10;
o
}
o
while(len(c) > 1 && c[len(c)-1] == 0) len(c)--;
o
}
除法:
o
void chu(long* a, long*b, long* c)//c = a / b
o
{
o
long *p = (long*)malloc(sizeof(long)*MAXN),
o
*q = (long*)malloc(sizeof(long)*MAXN),
o
*ten = (long*)malloc(sizeof(long)*MAXN),
o
*tmp = (long*)malloc(sizeof(long)*MAXN),i,cnt;
o
o
change("0",p); len(q) = 1; change("10",ten);
o
len(c) = len(a);
o
memset(c,0,sizeof(long)*len(c));
o
for (i=len(a)-1; i>=0; i--)
o
{
o
q[0] = a[i];
o
copy(tmp,p); cheng(tmp,ten,p);// p = p * 10
o
jia(p,q,p);// p = p + q
o
o
cnt = 0;
o
while(!xiao(p,b))//
用减法试商的过程
o
{
o
jian(p,b,p);
o
cnt++;
o
}
o
c[i] = cnt;
o
}
o
while(len(c) > 1 && c[len(c)-1] == 0) len(c)--;
o
o
free(p); free(q); free(tmp); free(ten);//:-)
o
}
}
如果能保证a,b无用的数据都是0的话(譬如是全局变量),那么处理多余进位问题的那个循环可以省略.