何时使用高精度?
int 最大数的数位为10位,即大约为2*(32-1)=2,147,483,648,取值范围-231~(231-1),大约为109
unsigned int 最大数的数位为10位,即大约为2*32=4,294,967,296,取值范围0~(232-1),大约为109
long long 最大数的数位19,即大约为2^(64-1)=9,223,372,036,854,775,808,取值范围-263~(263-1),大约为1018
unsigned long long 最大数的数位20,即大约为2^64=18,446,744,073,709,551,616,取值范围0~(264-1),大约为1019
超过10^19数量级一般选用Java大数解决
高精度操作
高精度结构体
struct bign {
int d[100];
int len;
bign() {
memset(d, 0, sizeof(d));
len = 0;
}
};
字符数组转换为高精度
bign change(char str[]) {
bign a;
a.len=strlen(str);
for(int i=0; i<a.len; i++) {
a.d[i]=str[a.len-1-i];
}
return a;
}
高精度乘低精度
bign multi(bign a, int b) {
bign c;
int r = 0;
for(int i=0; i<a.len; i++) {
int t = a.d[i]*b+r; //当前数字乘积
c.d[c.len++] = t%10; //取当前乘积的个位
r = t/10; //更新余数
}
while(r!=0) { //处理未处理的高位余数
c.d[c.len++]=r%10;
r /= 10;
}
return c;
}
高精度除以低精度
bign divid(bign a, int b, int &r) {
bign c;
c.len=a.len; //商和被除数位数一一对应
for(int i=0; i<a.len; i++) {
int t = r*10+a.d[i];
if(t<b) { //不够除,当前位为0
c.d[i]=0;
} else { //够除,
c.d[i]=t/b;
r = t%b;
}
}
while(c.len-1>=1&&c.d[c.len-1]==0) c.len--; //处理高位0
return c;
}
高精度加法
bign add(bign a, bign b) {
bign c;
int r = 0;
for(int i=0; i<a.len; i++) {
int t = a.d[i]+b.d[i]+r;
c.d[c.len++]=t%10; //取个位数
r = t/10; //更新余数
}
if(r!=0)c.d[c.len++]=r;//处理最后的进位
return c;
}
高精度减法
bign sub(bign a, bign b) {
bign c;
int r=0;
for(int i=0; i<a.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.len-1>=1&&c.d[c.len-1]==0)c.len--; //处理高位的0
return c;
}