大数计算(进阶) 支持大浮点数的任意精度加减乘除

上一篇实现了大数加法,乘除法都是简单的复用加法,这样做时间复杂度高,精度低。

进阶:

1.乘法模拟竖式计算方法 核心思路是num1[i]*num2[j]的结果一定对应乘积中的[i+j]位,并且考虑对[i+j+1]位的进位。

    这样的时间复杂度为O(m*n) 而简单的复用加法的时间复杂度为 (q/p)*(n+m)其中q,p为大数的实际值,n,m为大数的位数,这样当p很小的时候,时间复杂度会很大。进一步优化的方法是使用FFT即快速傅里叶变换。下一篇中进行升级。

	Num by(Num& a,Num&b)
	{
		Num ret;
		int pos1=a._float.length();
		int pos2=b._float.length();

		string s1,s2,s(1000,'0');
		s1=a._int+a._float;
		s2=b._int+b._float;

		reverse(s1.begin(),s1.end());  
        reverse(s2.begin(),s2.end());  
        for(int i=0;i<s1.length();i++)  
			for(int j=0;j<s2.length();j++)  
			{  
				int temp=(s1[i]-'0')*(s2[j]-'0');  
				s[i+j+1]=s[i+j+1]-'0'+(s[i+j]-'0'+temp)/10+'0';  
				s[i+j]=(s[i+j]-'0'+temp)%10+'0';  
			}
		reverse(s.begin(),s.end());  
		ret._int=s;
		int pos=s.length()-pos1-pos2+1;
		ret._int.resize(pos);
		ret._int[pos-1]='\0';

		int len=pos1+pos2;
		string::reverse_iterator rts=s.rbegin();
		while(rts!=s.rend()&&len>0)
		{
			ret._float.insert(0,1,*rts);
			rts++;
			len--;
		}

		if(a._sign==b._sign)
			ret._sign=POSITIVE;
		else 
			ret._sign=NEGATIVE;


		ret._int=ret.InputNum(ret._int).second._int;
		return ret;
	}


2.除法模拟竖式计算。为满足浮点计算,引入新的标志:精度。每一个大数对象都拥有一个进度,在运算除法时,返回的结果精度由被除数的精度,除数的小数位数共同决定。

核心算法为大数除以整数。处理两个浮点大数相除的时候,将两个大数的小数位对齐到整数位,记录对齐位数。将被除数的整数位额外对齐 10e精度 倍。计算结束后,取结果的0~精度-1为整数位,精度~end为小数位 处理符号位后返回计算结果。

	Num except(Num& a,Num& b)
	{
		int len1=a._float.length();
		int len2=b._float.length();
		int _precision=a._pos;
		string aa=a._int+a._float;
		string bb=b._int+b._float;
		string tmp;
		string ans;
		Num cop1,cop2,ret;
		int ok=0;
		for(int i=0;i<len1;i++)
		{
		bb+='0';
		}
		for(int i=0;i<len2+_precision;i++)
		{
		aa+='0';
		}
		cop2._int=bb;
		for(int i=0;i<aa.size();i++)
		{
			tmp+=aa[i];
			cop1._int=tmp;
			if(cop1>=cop2)
			{
			ok=1;
			int ex=(_exc(tmp,bb));
			ans+=(ex+'0');
			//char arr[3]={0};
			//itoa(ex,arr,10);
			Num ttmp;
			ttmp._int+=ex+'0';
			tmp=reduce(cop1,by(cop2,ttmp))._int;
			}
			else/* if(ok==1)*/
			{
				ans+='0';
			}
		}
		/*****************************核心算法****事实上要处理除数是字符串,以及提高运算精度等问题**********
                           // for(int i=0;i<s.size();i++)  
                           // {  
                           // cmp=(cmp*10+s[i]-'0');  
                           // if(cmp>=x)  
                           // {  
                           // ok=1;  
                           // ans+=(cmp/x+'0');  
                           // cmp%=x;  
                           // }  
                           // else{  
                           // ans+='0'; 
                           // }  
                           // }  
		******************************************************************************************/
		string::iterator it=ans.begin();
		int intlen=ans.length()-_precision;
		while(it!=ans.end()&&intlen>0)
		{
			ret._int+=*it
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值