高进度算法-补码运算

来源:互联网 发布:手机dns优选软件 编辑:程序博客网 时间:2024/06/14 02:41


orz CYX


针对带负数的高精度数运算,可以采用补码表示法。

补码表示法即用原码表示正数,补码表示负数。


补码表示法表示的任何数之间都可以进行加法运算,舍弃了减法,简化了代码。

对于乘法运算,先将补码表示的负数转化为正数,运算之后得到若为正数,再转化为负数。


//补码高精度算法。#include#include#include#define R register#define ll long long#define base 1000000000#define dmax(_a,_b)(_a)>(_b)?(_a):(_b)using namespace std;struct BigNum{int num[10010],len;void clear(){memset(num,0,sizeof(num));len=1;}inline void flip(){R int i;for(i=1;i<=len&&!num[i];++i);if(i>len)return;num[i]=base-num[i];for(++i;i<=len;++i)num[i]=base-1-num[i];num[len]-=base;}void scan(const char *ss){R int i,j,k,rev=0,cnt=1;while(ss[0]<'0'||ss[0]>'9'){if(ss[0]=='-')rev=1;++ss;}memset(num,0,sizeof(num));for(i=0;ss[i]>='0'&&ss[i]<='9';++i);for(j=i-1,k=1;j>=0;--j){num[k]+=cnt*(ss[j]-'0');cnt=(cnt<<3)+(cnt<<1);if(cnt==base)cnt=1,++k;}if(!num[k])--k;len=k;if(rev)flip();}void print(){R int rev=0,i;if(num[len]<0)rev=1,flip(),printf("-");while(len>1&&!num[len])--len;printf("%d",num[len]);for(i=len-1;i>=1;--i)printf("%09d",num[i]);if(rev)flip();}inline BigNum operator + (const BigNum &b1)const{R BigNum ret;ret.clear();R int i,flow=0;ret.len=dmax(b1.len,len);for(i=1;i<=ret.len;++i){ret.num[i]=num[i]+b1.num[i]+flow;flow=ret.num[i]/base,ret.num[i]%=base;while((flow>0||i1&&!num[len])--len;if(b1.num[b1.len]<0)b1.flip(),rev2=1;while(b1.len>1&&!b1.num[b1.len])--b1.len;ret.len=len+b1.len;for(i=1;i<=len;++i)for(j=1;j<=b1.len;++j){tmp=ret.num[i+j-1]+(ll)num[i]*b1.num[j];ret.num[i+j-1]=tmp%base,ret.num[i+j]+=tmp/base;}while(ret.len>1&&!ret.num[ret.len])--ret.len;if(rev1)flip();if(rev2)b1.flip();if(rev1^rev2)ret.flip();return ret;}};char q1[10010],s[10010];struct BigNum q2[2010];int n;int main(){R int i,j,k,des;R int t1=0,t2=0;R BigNum sum;scanf("%s",s+1);n=strlen(s+1);s[0]='(',s[n+1]=')',s[n+2]='\0',++n;for(i=0;i<=n;){des=-1;if((s[i]=='+'||s[i]=='-'||s[i]==')')&&q1[t1]=='*'&&s[i-1]!='*'){sum.clear(),sum.num[1]=1;while(q1[t1]=='*')sum=sum*q2[t2],--t1,--t2;sum=sum*q2[t2],q2[t2]=sum;}if(s[i]==')'){sum.clear();while(q1[t1]!='('){if(q1[t1]=='+')sum=sum+q2[t2];else q2[t2].flip(),sum=sum+q2[t2];--t1,--t2;}--t1,q2[t2]=sum+q2[t2];}if( ((s[i]=='-'||s[i]=='+')&&( (s[i+1]>='0'&&s[i+1]<='9' ) || s[i+1]=='-' ||s[i+1]=='+' )) || (s[i]>='0'&&s[i]<='9') ){if(s[i-1]!='*'&&s[i-1]!='(')q1[++t1]='+';q2[++t2].scan(s+i);des=i;while(s[des]<'0'||s[i]>'9')++des;while(s[des]>='0'&&s[des]<='9')++des;}else{if(s[i]!=')')q1[++t1]=s[i];des=i+1;}if(des!=-1)i=des;}q2[t2].print();return 0;}



原创粉丝点击