我开始用的代码:
/******************************************************************************
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;
}