首页 > 代码库 > 正数相减少
正数相减少
我开始用的代码:
/****************************************************************************** Copyright (C), 2001-2011, Huawei Tech. Co., Ltd. ****************************************************************************** File Name : Version : Author : Created : 2009/10/10 Last Modified : Description : Function List : History : 1.Date : 2009/10/10 Author : Modification: Created file ******************************************************************************/ #include <stdlib.h> #include <iostream> #include <string> #include <sstream> using namespace std; int a[40]={0},b[40]={0}; int term[40]={11}; //有效数字从 [0,j)开始的 return :the position小数点 c[i]=11处 int partition(const char* s,int c[]) { int len=strlen(s); int j=0; for(int i=0;i<len;i++) { switch(s[i]) { case '0': if(j==0) { c[j]=11; j--; break; }else { a[j]=0; break; } case '1':c[j]=1;break; case '2':c[j]=2;break; case '3':c[j]=3;break; case '4':c[j]=4;break; case '5':c[j]=5;break; case '6':c[j]=6;break; case '7':c[j]=7;break; case '8':c[j]=8;break; case '9':c[j]=9;break; case '.':c[j]=10;break; } j++; c[j]=11; } c[j]=11; int i; for(i=0;c[i]!=11;i++) { if(c[i]==10) return i; } return i; } double sub(int *a,int *b,int e,int k,int e2,int k2) { int l=(e-k)>(e2-k2)?(e-k):(e2-k2);//包含小数点到后面的长度 int l2=k>k2?k:k2;//小数点前的长度 int len=l+l2; for(int i=0;i<len;i++) term[i]=0; for(int i=1;i<l;i++) { if(k+i>=e) a[k+i]=0; if(k2+i>=e2) b[k2+i]=0; term[l2+i]=a[k+i]-b[k2+i]; } term[l2]=10; for(int i=0;i<l2;i++) { if(k2-i-1<0) { term[l2-i-1]=a[k-i-1]; }else term[l2-i-1]=a[k-i-1]-b[k2-i-1]; } //处理进位 for(int i=len-1;i>=0;i--){ if(term[i]<0) { if(term[i-1]==10) { term[i-2]=term[i-2]-1; }else term[i-1]=term[i-1]-1; term[i]+=10; } } string str; for(int i=0;i<len;i++) { char ch; if(term[i]==10) ch='.'; else ch=term[i]+'0'; str+=ch; } //cout<<str<<endl; stringstream stream(str); double d; stream>>d; return d; } double Decrease2(const char *s,const char *s2)//假设s>s2 { int k=partition(s,a); int i,e,e2,h,h2;//h表示从小数点开始的长度 for(i=0;a[i]!=11;i++); e=i;//[0,e) 小数点位置在k h=e-k; int k2=partition(s2,b); for(i=0;b[i]!=11;i++); e2=i; h2=e2-k2; return sub(a,b,e,k,e2,k2); } int cmp(int a[],int b[],int k,int k2)//比较 a[0..k) 到b[0,..k2) { if(k>k2) return 1; if(k<k2) return -1; for(int i=0;i<k;i++) { if(a[i]==b[i]) continue; if(a[i]>b[i]) return 1; else return -1; } return 0; } int Judge(const char *s, const char *s2)//判断正负数 { int k=partition(s,a); int i,e1,e2,h,h2;//h表示从小数点开始的长度 for(i=0;a[i]!=11;i++); e1=i;//[0,e) 小数点位置在k h=e1-k; int k2=partition(s2,b); for(i=0;b[i]!=11;i++); e2=i; h2=e2-k2; /*比较整数部分*/ int res=cmp(a,b,k,k2); if(res!=0) return res; if(e1<e2) { for(i=0;i<e2-e1;i++) { a[e1+i]=0; } }else if(e1>e2) { for(i=0;i<e1-e2;i++) b[e2+i]=0; } int e=e1>e2?e1:e2; res=cmp(a,b,e,e); return res; } /***************************************************************************** Description : 两个任意长度的正数相减 Prototype : int Decrease(const char *pMinuend, const char *pSubtrahend, char **ppResult) Input Param : const char *pMinuend 被减数,以\0表示字符串结束 const char *pSubtrahend 减数,以\0表示字符串结束 Output : char **ppResult 减法结果,必须以\0表示字符串结束 Return Value : 成功返回0 失败返回-1 *****************************************************************************/ int Decrease(const char *pMinuend, const char *pSubtrahend, char **ppResult) { /* 在这里实现功能 */ if(pMinuend == NULL || pSubtrahend == NULL || pMinuend[0] == '\0' || pSubtrahend[0] == '\0') return -1; double d; int flg=Judge(pMinuend,pSubtrahend); if(flg==1) d=Decrease2(pMinuend,pSubtrahend); else if(flg==-1) d=Decrease2(pSubtrahend,pMinuend); else { *ppResult=new char[2]; (*ppResult)[0]='0'; (*ppResult)[1]='\0'; return 0; } if(flg==-1) d=-1*d; //cout<<"d="<<d<<endl; char out[100]={0}; stringstream stream; stream<<d; stream>>out;// 可能溢出了 没法解决 int len=strlen(out); *ppResult=new char[len+1]; sprintf(*ppResult,"%s",out); (*ppResult)[len]='\0'; //cout<<*ppResult<<endl; return 0; }结果提交上去,20个例子通过13个,我没有想到任何大的数据 用string 表示,
首先用一个函数表示一个大数-小数,a>b a-b
将a=aa.ab b=ba.bb
拆分
首先减法,后进位
比如 1234.34 - 987.45 正数部分 1 -3 -5 -3 小数部分 -1 -1
进位操作: 小数 8 9 正数 0 6 4 6
去掉没用的0 即可
具体代码如下:
string Decrease3(string aa,string ab,string ba,string bb)//a>b 的时候 aa.ab ba.bb { int len=aa.length()>ba.length()?aa.length():ba.length();//整数部分的长度 int len2=ab.length()>bb.length()?ab.length():bb.length();//小数部分的长度 int* A=new int[len]; int *B=new int[len2]; int i,Carry=0; /*整数部分*/ int aa_length=aa.length(); int ba_length=ba.length(); for(i=0;i<len;i++) { if(ba_length-i-1<0) { A[len-i-1]=aa[aa_length-i-1]-'0'; }else A[len-i-1]=aa[aa_length-i-1]-ba[ba_length-i-1]; } /*小数部分*/ int ab_length=ab.length(); int bb_length=bb.length(); for(int i=0;i<len2;i++) { if(i>ab_length-1) B[i]='0'-bb[i]; else if(i>bb_length-1) B[i]=ab[i]-'0'; else B[i]=ab[i]-bb[i]; } /*处理进位*/ for(i=len2-1;i>=0;i--) { if(B[i]<0) { if(i-1>=0) { B[i-1]=B[i-1]-1; }else Carry=-1; B[i]+=10; } } if(Carry==-1) A[len-1]=A[len-1]-1; for(i=len-1;i>=0;i--) { if(A[i]<0) { A[i-1]=A[i-1]-1; A[i]=A[i]+10; } } string res=""; char ch; for(i=0;i<len;i++) { ch=A[i]+'0'; res=res+ch; } res=res+"."; for(i=0;i<len2;i++) { ch=B[i]+'0'; res=res+ch; } /*delete zero xxx.xxx0000*/ size_t pos=res.find_first_of("."); int s2,t2; for(s2=0;s2<res.length();s2++) { if(res[s2]>'0'&&res[s2]<='9') break; } for(t2=res.length()-1;t2>=0;t2--) { if(res[t2]>'0'&&res[t2]<='9') break; } string tmp=""; if(pos<s2) { tmp=res.substr(pos-1,res.length()-pos+1); }else tmp=res.substr(s2,t2-s2+1); delete A; delete B; return tmp; } /***************************************************************************** Description : 两个任意长度的正数相减 Prototype : int Decrease(const char *pMinuend, const char *pSubtrahend, char **ppResult) Input Param : const char *pMinuend 被减数,以\0表示字符串结束 const char *pSubtrahend 减数,以\0表示字符串结束 Output : char **ppResult 减法结果,必须以\0表示字符串结束 Return Value : 成功返回0 失败返回-1 *****************************************************************************/ int Decrease(const char *pMinuend, const char *pSubtrahend, char **ppResult) { /* 在这里实现功能 */ if(pMinuend == NULL || pSubtrahend == NULL || pMinuend[0] == '\0' || pSubtrahend[0] == '\0') return -1; string a=pMinuend; string b=pSubtrahend; string aa=""; string ab=""; string ba=""; string bb=""; size_t a_index=a.find_first_of("."); size_t b_index=b.find_first_of("."); aa=a.substr(0,a_index);//[0,a_index) if(a_index!=string::npos) ab=a.substr(a_index+1,a.length()-a_index-1);//[a_index+1,a.length()) ba=b.substr(0,b_index);//[0,a_index) if(b_index!=string::npos) bb=b.substr(b_index+1,b.length()-b_index-1);//[b_index+1,b.length()) int flg=0;//符号 a>b 1 a<b -1 a==b 为0 if(aa.length()>ba.length()) { flg=1; }else if(aa.length()<ba.length()) { flg=-1; }else// 整数部分的位数相等 { flg=aa>ba?1:-1; if(aa>ba) flg=1; else if(aa<ba) flg=-1; else flg=0; if(flg==0) { if(ab==bb) flg=0; else if(ab>bb) flg=1; else flg=-1; } } string res; if(flg==0) { *ppResult=new char[2]; (*ppResult)[0]='0'; (*ppResult)[1]='\0'; return 0; }else if(flg==1) { res=Decrease3(aa,ab,ba,bb); }else { res=Decrease3(ba,bb,aa,ab); res="-"+res; } int len=res.length(); *ppResult=new char[len+1]; char *p=*ppResult; for(int i=0;i<len;i++) { *p=res[i]; p++; } *p='\0'; return 0; }
正数相减少
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。