高精度四则运算模板

高精度乘法 
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#define N 300000
using namespace std;
char aa[N],bb[N];
int lena,lenb,a[N],b[N],ans[N],len,nxt,tmp;
int main()
{
	scanf("%s%s",aa+1,bb+1);lena=strlen(aa+1);lenb=strlen(bb+1);
	for(int i=1;i<=lena;i++) a[lena-i+1]=(aa[i]-'0');
	for(int i=1;i<=lenb;i++) b[lenb-i+1]=(bb[i]-'0');
	if(lena<lenb) {for(int i=1;i<=lenb;i++) swap(a[i],b[i]);swap(lena,lenb);}
	for(int i=1;i<=lenb;i++)
	{
		nxt=0;
		for(int j=1;j<=lena;j++)
		{
			tmp=(a[j]*b[i]+nxt);
			ans[i+j-1]+=tmp;
			nxt=ans[i+j-1]/10;ans[i+j-1]%=10;
		}
		if(nxt) ans[i+lena]+=nxt;
	}
	len=lena+lenb;
	while(len && !ans[len]) len--;
	if(!len)
	{
		printf("0");return 0;
	}
	while(len) printf("%d",ans[len]),len--;
	return 0;
}


高精度减法
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#define N 300000
using namespace std;
char aa[N],bb[N];
int lena,lenb,a[N],b[N],ans[N],len;
void check()
{
	if(lena<lenb) 
	{
		printf("-");
		for(int i=1;i<=lenb;i++) swap(a[i],b[i]);
		swap(lena,lenb);
	}else if(lena==lenb)
	{
		len=lena;
		while(len && a[len]==b[len]) len--;
		if(a[len]<b[len])
		{
			printf("-");
			for(int i=1;i<=lenb;i++) swap(a[i],b[i]);
		}
	}	
}
int main()
{
	scanf("%s%s",aa+1,bb+1);lena=strlen(aa+1);lenb=strlen(bb+1);
	for(int i=1;i<=lena;i++) a[lena-i+1]=(aa[i]-'0');
	for(int i=1;i<=lenb;i++) b[lenb-i+1]=(bb[i]-'0');
	check();
	len=1;
	while(len<=lena)
	{
		if(a[len]<b[len]) a[len+1]--,a[len]+=10;
		ans[len]=a[len]-b[len];
		len++;
	}
	len=lena;
	while(len && !ans[len]) len--;
	if(!len) printf("0");
	else
	{
		while(len) printf("%d",ans[len--]);
	}
	return 0;
}



高精度加法
 
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#define N 300000
using namespace std;
char aa[N],bb[N];
int lena,lenb,a[N],b[N],ans[N],len;
int main()
{
	scanf("%s%s",aa+1,bb+1);lena=strlen(aa+1);lenb=strlen(bb+1);
	for(int i=1;i<=lena;i++) a[lena-i+1]=(aa[i]-'0');
	for(int i=1;i<=lenb;i++) b[lenb-i+1]=(bb[i]-'0');
	for(int i=1;i<=lena;i++)
	{
		b[i]+=a[i];
		b[i+1]+=b[i]/10;
		b[i]%=10;
	}
	len=lena+1;
	while(len<=lenb && b[len]>=10)
	{
		b[len+1]+=(b[len]/10);
		b[len]%=10;
	}
	if(b[lenb+1]) lenb++;
	while(lenb) printf("%d",b[lenb--]);
	return 0;
}
*/


高精除法:保留小数。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<vector> 
#include<iterator>
#include<cstdio>
using namespace std;
string a,b,d="0",bb="0";
int dif,dns=0,r,all=0;
int lena,lenb,qq=0;//qq记录小数点是否已经输出 
vector<int>c;
void change(string x,string y)//这里的减法和我写的独立的减法程序一样,不再赘述
{
    c.clear();
    dif=abs(x.length()-y.length());//长度的差值 
    int len=max(x.length(),y.length());
    for(int i=len-1;i>=0;i--)
    {
        int a=x[i]-'0'+dns,b=y[i-dif]-'0';
        if(len-i > y.length()) {
            b=0;
        }
        int p=a-b;
        dns=0; 
        if (p < 0) {
            p+=10;
            dns=-1;
        }
        c.push_back(p);
    }
}
void handle()
{
    int num=0;
    while(a.length() > b.length() || (b.length() == a.length() && a >= b))
    {//只是将除法的过程改为了减法,而这一步就是确定商多少
        num++;//每减一次商累加一
        change(a,b);
        int con=1;
        a="0";
        for(int i=c.size()-1;i>=0;i--)//把余数重新转化为string 
        {
            if(c[i]==0&&con)
            {
                continue;
            }
            con=0;
            if(a == "0") a=char(c[i]+48);//0的阿斯科玛是48
            else a=a+char(c[i]+48);
        }//为了不再更改之前写的高精度减法的基础,这里只能将余数转换成string的形式
        //之前其实没用char(c[i]+48)的形式但是出现了各种错误,最后才发现这样可以
    }
    cout<<num;//输出得到的商的当前位,当然如果希望得到结果的话也可以将它存起来
    if(a == "0" ) exit(0);//对于小于的情况,如果余数等于0了一定是已经除尽
    int con=1;
    while(a.length() < b.length() || (b.length() == a.length() && a < b))
    {//余数后面补零,使余数大于除数
        if(con--) a=a+char(48);//如果只补一次,自然结束了
        else //但是如果补了两个0的话,一定会得到一个商是0,这时应该输出
        {
            cout<<"0";
            a=a+char(48);
        }
    }
}
int main()
{
    cin>>a>>b;
    if(b=="0")
    {
        cout<<"-1";
        return 0;
    }
    lena=a.length();
    lenb=b.length();
    if(a == b)
    {
        cout<<"1";
        return 0;
    }
    if(lena < lenb || (lena == lenb && a < b))//如果被除数小于除数,先输出“0.”,再将被除数加一
    {
        cout<<"0.";
        a+="0";
        while(a.length() < b.length() || (b.length() == a.length() && a < b))//有可能出现加一后被除数仍然小于除数,这时应该继续加
        {
            a+="0";
            cout<<"0";//为了模拟手动除法,每次给被除数加末尾数字的时候都应该输出0
        }
        while(all <= 100)//all用来控制输出的位数,这里是输出的小数点后的位数
        {
            handle();//其实这里的handle改自高精度减法的main函数
            all++;
        }
    }
    else//被除数大于除数和小于除数的情况差别很大,所以分开写
    {
        r=lenb-1;//记录a中已经读到的位置
    //还是模拟除法,每次得到商的一位后都应该从被除数上降下一位到余数,而r就是记录从那里降
    //之前大于的情况在因为被除数已经没有位可以降,所以是直接降0,而这里显然不可以
        for(int i=0;i<lenb;i++)//将所选区间转化为string形式 
        {
            if(d == "0") d=a[i];
            else d+=a[i];
        }
        while(d.length() < b.length() || (d.length() == b.length() && d < b)) {
            d+=a[++r];
        }//还是考虑到可能所选区间不够大
        while(all <= 100)
        {
            int num=0;
            while(d.length()>lenb||(d.length()==lenb && d>=b ))
            {
                num++;
                change(d,b);//减法过程
                int con=1;
                d=bb;
                for(int i=c.size()-1;i>=0;i--)
                {
                    if(c[i]==0&&con)continue;
                    con=0;
                    if(d == "0") d=char(c[i]+48);
                    else d=d+char(c[i]+48);
                }
            }
            cout<<num;
            if(r+1 == lena && d == "0") break;
            if(r+1 == lena )
            {
                if(!qq)
                {
                    cout<<".";
                    qq=1;
                }
                d=d+char(48);
            }
            else d=d+a[++r];
            all++;
        }
    }
    return 0;
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值