所谓大数,就是数字非常(*100)的大,不管是int还是long long int都存储不下的数,如何进行加减乘除四则运算,这种情况在计算机的运算中还是很常见的,现将大致思路写上,并附上代码以供参考。
整体思路
首先数据必然是不能以int或者long long int存储,那么只能以字符串或者字符数组的形式存储。而且实际上,以字符数组接收数据最佳,然后把字符数组转化为int数组,再对数字进行计算。
其次,联想起我们小学二年级所学的加减乘除四则运算,我们会发现一个最基本的规律:
- 加减乘:从右往左计算
- 除法:从左往右计算
这就提示我们,数据需要进行一下处理,因为输入的数据是不定长的,所以我们需要把数据对齐。也就是说我们需要在加减乘,将数据倒过来,个位对个位,十分位对十分位;但是在除法中,我们只要按从左往右接收数据就可。
数据结构
int数组没有不能像字符数组那样,可以直接获取长度,所以最初想法就是在转化int数组的时候,再加上一个变量len,标记数组长度。
#define MAX 1000
struct bigNum{
int n[MAX];
int len;
bigNum(){
memset(n, 0, sizeof(n));
len = 0;
}
};
数据处理
根据上边的思路,我们需要将char型数组转化为int型数组,而且是倒序,这样保证从个位开始对齐,方便加减乘运算,而除法只需要将char型数组转化为int型数组就可。
当然还有一些其他的工具,比如比较两个bigNum的大小,这在减法和除法上需要用到,还有除法采用的是减法思想,所以除法的数组顺序也要有个调整。
// 加减乘处理使用
bigNum transfer(char str[]){
bigNum bn;
bn.len = strlen(str);
int i;
for(i=0; i<bn.len; i++)
bn.n[i] = str[bn.len-1-i] - '0';
return bn;
}
// 除法处理使用
bigNum transferSort(char str[]){
bigNum bn;
bn.len = strlen(str);
int i;
for(i=0; i<bn.len; i++)
bn.n[i] = str[i] - '0';
return bn;
}
// 加减乘处理使用
int compare(bigNum a, bigNum b){
if(a.len > b.len) return 1;
else if(a.len < b.len) return -1;
else{
int i;
for(i=a.len-1; i>0; i--){
//高位比较
if(a.n[i] > b.n[i]) return 1;
else if(a.n[i] < b.n[i]) return -1;
else return 0;
}
}
}
// 除法处理使用
int compareSort(bigNum a, bigNum b){
if(a.len > b.len) return 1;
else if(a.len < b.len) return -1;
else{
int i;
for(i=0; i<a.len; i++){
//高位比较
if(a.n[i] > b.n[i]) return 1;
else if(a.n[i] < b.n[i]) return -1;
else return 0;
}
}
}
// 倒序,除法用
void reverse(int a[], int len){
int i;
for(i=0; i<len/2; i++){
int temp = a[i];
a[i] = a[len-1-i];
a[len-1-i] = temp;
}
}
大数加法
bigNum add(bigNum a, bigNum b){
// a+b
bigNum c;
int flag = 0;
int len = (a.len > b.len) ? a.len : b.len;
int i;
for (i=0; i<len; i++){
int temp = a.n[i] + b.n[i] + flag;
flag = (temp >= 10) ? 1 : 0;
c.n[c.len++] = temp % 10;
}
// 处理进位情况
if(flag != 0)
c.n[c.len++