如果遇到1000位的加减,只能通过模拟来确定精度
定义int 型数组存储大整数。
原则:整数的高位存储在数组的高位,整数的低位存储在数组的低位,因为在进行运算的时候都是从整数的低位到高位进行枚举,顺位存储和这种思维相吻合。
因此实际上是逆位存储,再度入后需要在另存为数组的时候反转。
定义结构体并初始化
struct bign{ int d[1000]; 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-i-1]-'0';//倒序赋值 } return 0; }
如何比较这两个大整数
先比较位数,如果位数不同直接比较谁大,如果位数相同,则从高位开始循环比较
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; }
两个大整数相加:从低位开始每位相加,然后进位保存在一个临时int中,每次每位相加需要把临时int加上
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 0; }
两个大整数相减:低位向高位借位,并且最高一位如果为0则抹去
big 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]; } 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){//和加法不一样,乘法的进位可能不止一位,用while c.d[c.len++]=carry%10; carry/=10; } return c; }
高精度与低精度的除法,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; } else{ c.d[i]=r/b; r=r%b; } } while(c.len-1>=1&&c.d[c.len-1]==0){ c.len--; } return c; }