(C++)高精度整数的存储读入比较和四则运算
Posted CSU迦叶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(C++)高精度整数的存储读入比较和四则运算相关的知识,希望对你有一定的参考价值。
目录
高精度整数,又称大整数,其含义就是用基本数据类型无法存储其精度的整数。如:10进制下有着1000个数位的整数。
低精度整数,就是可以用基本数据类型存储的整数。
1. 存储
采用整型数组顺位存储,即整数高位存储在数组高位。为了方便随时获取长度,因此定一个int len和int []组成结构体bign(取自big number)。
同时在结构体中使用构造函数,进行初始化。
struct bign{
int d[1000];
int len;
bign(){
memset(d,0,sizeof(d));
len = 0;
}
};
2. 读入
作为字符串读入,再把字符串另存至bign结构体。
由于是顺位存储,因此字符串要逆着输进结构体数组,同时记得 -‘0’ 将字符转化为整数
下面是将字符串转化为bign结构体的函数
bign change(char s[]){
bign bg;
bg.len = strlen(s);
for(int i=0;i<bg.len;i++){
bg.d[i] = s[bg.len-1-i] - '0';
}
return bg;
}
3. 比较大小
原理:先比较两个大整数的长度,更大的直接胜出;从高位到低位逐位比较大小,直至出现某一位不相等,那一位上更大胜出。
结果为int型,如果第一个大于第二个,返回1,等于返回0,小于返回-1。
int compare(bign a,bign b){
if(a.len>b.len)return 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;
else if(a.d[i]<b.d[i])return -1;
}
return 0;
}
}
4. 加法
原理:从低位到高位逐位相加,每一个和的个位保留在原位,十位进到更高位。
c = a + b (a>=0,b>=0 )
注意:遍历的过程中位数取a和b中位数更多的那个,结果可能超过a和b的长度。
bign add(bign a,bign b){
bign c;
int carry = 0;//进位
int sum;
for(int i=0;i<a.len||i<b.len;i++){
sum = a.d[i] + b.d[i] + carry;
c.d[c.len++] = sum%10;
carry = sum/10;
}
//对于高于a和b的那个位数是否有数字取决于进位的最后值
if(carry)c.d[c.len++] = carry;
return c;
}
注意,这里的加法只适用于两者都是非负的。如果有一个是负的,应该采用高精度减法,如果两个都是负的,就先转化成正的相加最后加上负号。
5. 减法
原理:从低位到高位逐位相减,不够的向上一位借。最后对结果的长度进行纠正,从最高位开始,如果那一位上的数字是0,那么长度减一,但是长度不会为0至少为1。
不用担心向高位借但是高位也是0,因为短暂变成-1之后在下一轮比较时会向更高位借。
c = a - b (a>=b>=0)
bign sub(bign a,bign b){
bign c;
for(int i;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];
}
while(c.d[c.len-1]==0&&c.len>1){//矫正位数,高位是0就长度减1,但是长度至少为1
c.len --;
}
}
注意:这里要求被减数不小于减数,如果不满足要求,需要先把两个数进行交换。
6. 高精度整数和低精度整数的乘法
得到的自然是高精度整数。
原理:bign从低位开始逐位和int的整体相乘,得到的结果个位保留在本位,其余高位(不是十位)进到下一步运算。
bign c = bign a * int b
bign multi(bign a,int b){
bign c;
int carry = 0;
int product;//乘积
for(int i;i<a.len;i++){
product = a.d[i]*b + carry;
c.d[c.len++] = product%10;
carry = product/10;
}
while(carry){//注意此处和加法的区别
c.d[len++] = carry % 10;
carry /= 10;
}
return c;
}
7. 高精度整数除以低精度整数
得到的是高精度整数(低精度实际上可以视为高精度的子集)。
原理:bign从高位到低位逐位对int进行除操作,除之前余数*10加上当前位(开始把余数写成引用“引用”的形式传入是为了直接对原变量进行修改,最后得到的余数也就是结果),如果不够除(当前位已经被加到余数中),则当前位记为0,够除则将除得的商留在当前为,除得的余数用来更新余数。
(a + r)/b = c 余数r(存到传进的作为余数的变量r)
bign divide(bign a,int b,int& r){//调用的时候r是int类型的
bign c;
c.len = a.len;
for(int i = c.len-1;i>=0;i--){
r = r*10 + a.d[i];
if(r<b)c.d[i]=0;
else{
c.d[i] = r/b;
r = r%b;
}
}
//矫正位数
while(c.d[c.len-1]==0&&c.len>1){//矫正位数,高位是0就长度减1,但是长度至少为1
c.len --;
}
return c;
}
summary:
加和乘最后需要根据进位有无增加长度(新增位上当然要有数值)
减和除最后需要根据高位有无减少长度(但是边界是长度至少为1)
以上是关于(C++)高精度整数的存储读入比较和四则运算的主要内容,如果未能解决你的问题,请参考以下文章