大整数储存方法:
很简单,使用数组即可。 例如定义int型数组d[1000], 那么这个数组中的每一位就代表了存放的整数的每一位。如将整数235813 存储到数组中,则有d[0] = 3, d[l] = 1, d[2] = 8, d[3] = 5, d[4] = 3, d[5] = 2, 即整数的高位存储在数组的高位, 整数的低位存储在数组的低位。 不反过来存储的原因是,在进行运算的时候都是从整数的低位到高位进行枚举,顺位存储和这种思维相合。但是也会由此产生一个需要注意的问题:把整数按字符串%s读入的时候,实际上是逆位存储的,即str[O] =‘2’, str[l] =‘3’, …,str[5] =‘3’, 因此在读入之后需要在另存为至d[]数组的时候反转一下。
储存代码如下:
struct bign{
int d[1000];
int len;
bign(){//初始化 “构造函数” 是用来初始化结构体的函数,
//函数名和结构体名相同、 无返回值,
//因此非常好写 因此大整数结构体bign 就变成了这样:
memset(d,0,sizeof(d));
len=0;
}
};
bign change(char str[]){//将整数转换为bign
bign a;
a.len=strlen(str);
for(int i=0;i<a.len;i++) a.d[i]=str[a.len-i-1]-'0';
return a;
}
大整数加法思路:
其实就是小学的加法,以 147 + 65 为例:
- 7 + 5 = 12, 取个位数 2 作为该位的结果, 取十位数 1 进位。
- 4+6, 加上进位 1 为 11, 取个位数 l 作为该位的结果, 取十位数 1 进位。
- 1 +0, 加上进位 1 为 2, 取个位数 2 作为该位的结果,由于十位数位 0, 因此不进位。
由此思路可得代码如下:
#include<bits/stdc++.h>
using namespace std;
struct bign {
int d[1000];
int len;
bign() {
memset(d,0,sizeof(d));
len=0;
}
};
bign change(char str[]) { //将整数转换为bign
bign a;
a.len=strlen(str);
for(int i=0; i<a.len; i++) {
a.d[i]=str[a.len-i-1]-'0';
}
return a;
}
int compare(bign a,bign b) { //比较a和b的大小,a大,相等 ,小返回值分别是1,0,-1
if(a.len>b.len) return 1;//a大
else if(a.len<b.len) return -1;//a小
else {
for(int i=a.len-1; i>=0; i--) { //从高位往低位比较
if(a.d[i]>b.d[i]) return 1;//只要有一位a大,则a大
else if(a.d[i]<b.d[i]) return -1; //只要有一位 a小,则啊小
}
return 0;//两数相等
}
}
bign add(bign a,bign b) { //高精度a+b
bign c;
int carry=0;//carry是进位
for(int i=0; i<a.len||i<b.len; i++) { //较长的为界限
int temp=a.d[i]+b.d[i]+carry;//两个对应的位数与进位相加
c.d[c.len++]=temp%10;//个位数的结果
temp/=10;//十位数为新的进位
}
if(carry!=0) { //如果最后进位不为0,则直接赋给结果的最高位
c.d[c.len++]=carry;
}
return c;
}
void print(bign a) { //输出bign
for(int i=a.len-1; i>=0; i--) printf("%d",a.d[i]);
}
int main() {
char str1[1000],str2[1000];//以字符串形式存入
scanf("%s%s",str1,str2);
bign a=change(str1);//把char类型转换为bign
bign b=change(str2);
print(add(a,b));
return 0;
}
特别提醒:
这样写法的条件是两个对象都是非负整数。如果有一方是负的, 可以在转换
到数组这一步时去掉其负号, 然后采用高精度减法;如果两个都是负的, 就都去掉负号后用高精度加法, 最后再把负号加回去即可。
想要了解减法运算可以连接:大整数减法