①什么是大整数:高精度整数,用基本数据类型无法存储其精度的整数,例如有1000个位数的整数。
②存储:用数组,整数的高位存储在数组的高位,整数的低位存储在数组的低位。输出的时候逆序输出。
(1)大整数结构体:
struct bign{
int d[1000];
int len;//方便获取大整数的长度
//构造函数(函数名与结构体相同,无返回值)初始化结构体
bign(){
memset(d,0,sizeof(d));
len = 0;
}
};
(2)输入大整数,运用字符串,再存至结构体:
bign change(char str[]){
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;
}
③应用:
(1)比较两数大小
规则:先比长度,不等出结果;相等从高位到低位比较,直到不等得结果,都不满足则两数相等。
int compare(bign a,bign b){
//a比b大 ,返回1
if(a.len>b.len){
return 1;
}
//b比a大,返回-1
else if(a.len<b.len){
return -1;
}
//否则从高位到低位判断
else{
for(int i=a.len-1;i>=0;i--){
if(a.d[i]>b,d[i]) return 1;//a大返回1
else if(a.d[i]<b.d[i]) return -1;//b大返回-1
}
//否则相等,返回0
return 0;
}
}
(2)四则运算(模拟加减乘除的过程)
高精度加法:
bign add(bign a,bign b){
bign c;
int carry = 0;//进位
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;//个位结果
carry = temp/10;//新的进位
}
//判读最后的进位
if(carry!=0){
c.d[c.len++] = carry;
}
return c;
}
练习例子:
https://editor.youkuaiyun.com/md/?articleId=108066267
注意:该例子的两数都是非负整数。
高精度减法:
注意比较两数的大小;注意删掉高位的0。
bign sub(bign a,bign b){
bign c;
for(int i =0;i<a.len||i<b.len;i++){
if(a.d[i]<b.d[i]){
a.d[i+1]--;//高位减一
a.d[i] += 10;//低位加十
}
c.d[c.len++] = a.d[i] - b.d[i];//各位减的结果
}
//删除高位的0
while(c.len - 1>=1 && c.d[c.len - 1] ==0){
c.len --;
}
return c;
}
高精度与低精度(可以用基本数据类型存储)的乘法:
与平常的做法不太一样。
具体步骤位:
取bign的某位与int类型整体相乘,再与进位相加,得到的结果的个位作为该位结果,高位部分作为新的进位。
bign multi(bign a,int b){
bign c;
int carry = 0;
for(int i=0;i<a.len;i++){
int temp = a.d[i]*b +carry;
c.d[c.len++] = temp%10;//个位作为该位结果
carry = temp / 10;//高位部分作为新的进位
}
//乘法可能有多个进位,区别于加法
while(carry != 0){
c.d[c.len++] = carry %10;
carry /= 10;
}
return c;
}
高精度与低精度的除法:
具体步骤:
上一步的余数乘以10加上该位的数,得到临时的被除数,与除数比较,不够除,该位为0,够除,商就是对应的商,余数就是对应的余数。
注意高位为0需要删除
这里传递了三个参数,余数用的是引用。注意区别前面的三种运算。
//r是余数
bign divide(bign a,int b,int &r){
bign c;
//被除数每位与商的每位一一对应,故开始长度相等。
c.len = a.len;
//从高位开始相除
for(int i = a.len - 1;i>=0;i--){
//与上一位的余数组合
r = r*10+a.d[i];
if(r<b)c.d[i] = 0;//不够除,则为0
else{//够除
c.d[i] = r/b;//得到的商
r = r%b;//获得新的余数
}
}
//去掉高位0,同时保留至少一位。
while(c.len - 1 >= 1 && c.d[c.len-1]==0){
c.len --;
}
return c;
}
总结:四种情况有很多相似之处,注意区分,还是需要记住每种写法,才利于使用,总的来说还是很简单的。