大整数存储数组
用一个字符串读取输入的大数,在转换的时候,用反转的方式存到一个int型的数组中。ide
struct bign{ int d[1000]; int len; bigh(){ memset(d,0,sizeof(d)); len=0; } }
bign change(string str){ bign a; a.len=str.size(); for(int i=0;i<a.len;i++){ a.d[i]=str[a.len-i-1]-'0'; } return a; }
大整数比较大小spa
先判断二者的len大小,若是不鲜水果等,则以长的为大;若是相等,则从高位到低位进行比较,知道出现某一位不等,就能够判断两个数的大小。code
int compare(bign a,bign b){ if(a.len>b.len) return 1;//a大 else if(a.len<b.len) return -1;//b大 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小,则a小 } return 0;//两数相等 } }
高精度加法blog
用竖式的形式进行计算,对其中一位进行加法的步骤,将该位上的两个数字与进位相加,获得的结果取个位数做为该位的结果,取十位数做为新的进位。字符串
bign add(bign a,bign b){string
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;//取个位数做为该位结果 carry=temp/10; } if(carry != 0){ c.d[c.len++]=carry; } return c; }
高精度减法class
保证a>b。不然,交换位置,减法后先输出 “-”,再输出结果‘。循环
对某一步,比较被减位和减位,若是不够减,则令被减位的高位减一、被减位+10,再进行减法;若是够减,则一直减。最后一步要注意减法后高位可能有多余的0,要除去它们,但也要至少保证结果有一位数。di
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]--;//向高位借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; } bign before_sub(bign a,bign b){ bign c; if(compare(a,b)==-1){//a比b小的话 c=sub(b,a); printf("-"); }else{ c=sub(a,b); } for(int i=c.len-1;i>=0;i--){ printf("%d",c.d[i]); } }
高精度与低精度的乘法
以147*35为例,把147看做一个高精度bign类型,35看为int类型。下面操做中,35始终为一个总体。
一、7*35=245,取5做为该位的结果,高位部分24做为进位;
二、4*35=140,加上进位24,等于164,取个位4做为该位的结果,高位16为进位;
三、1*35=25,加上进位16,等于51,取1为该位的结果,高位5为进位。
四、没得乘了,进位不为0,把进位5直接做为该位的结果。
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,要除去它们,但也保证结果至少有一位。
bign divide(bign a,int b,int& r){//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; } } while(c.len-1>=1&&c.d[c.len-1]==0){ c.len--;//去除高位的0,但保证至少有一位数存在。 } return c; }