高精度算法

高精度算法小结

其实 高精==高阶模拟

怎么讲?

  • 高精加法:每一位对应相加,注意进位问题
  • 高精减法:每一位对应相减,注意退位问题
  • 高精乘法:每一位对应相加,注意进位问题

加法运算

每一位对应相加,满digit进1即可

#include <bits/stdc++.h>
using namespace std;
const int digit=10000;
const int maxx=4;
const int maxn=600;
char a[maxn],b[maxn];


struct Big
{
    int a[maxn],n;
    Big(){n=1;memset(a,0,sizeof(a));}
    int& operator [] (int x){return a[x];}
    Big(char *s)
    {
        memset(a,0,sizeof(a));
        int len=strlen(s);
        n=(len+maxx-1)/maxx;
        int t=0,w=1;
        for(int i=0;i<len;++i)
        {
            w=w*10;
            if(i%maxx==0){w=1;++t;}
            a[t]+=w*(s[i]-'0');
        }
    }
    void Print()
    {
        printf("%d",a[n]);
        for(int i=n-1;i>0;i--)
        {
            printf("%04d",a[i]);
        }
    }
}p,q,ans;

Big operator+(const Big &p,const Big &q)
{
    Big c;
    c.n=max(p.n,q.n);
    for(int i=1;i<=c.n;i++)
    {
        c[i]+=p.a[i]+q.a[i];
        c.a[i+1] += c.a[i] / digit;  
        c.a[i] %= digit;
    }
    if(c[c.n+1])++c.n;
    return c;
}

void init()
{
    freopen("Lg P1401.in","r",stdin);
}


void readdata()
{
    scanf("%s\%s",a,b);
    reverse(a,a+strlen(a));
    reverse(b,b+strlen(b));
    p=Big(a);
    q=Big(b);
    ans=p+q;
    ans.Print();
}

int main()
{
//	init();
    readdata();
    return 0;
}

减法运算

上述三种运算中,减法相对麻烦一些。注意判负

代码实现?
1.暴力模拟(见代码)
2.重载<运算符(见代码)

1.暴力模拟

#include <bits/stdc++.h>
using namespace std;
const int digit=10000;
const int maxx=4;
const int maxn=10005;
char a[maxn],b[maxn];
int f=1;
struct Big
{
	int a[maxn],n;
	Big(){n=1;memset(a,0,sizeof(a));}
	int& operator [] (int x){return a[x];}
	
	Big(char *s)
	{
		memset(a,0,sizeof(a));
		int len=strlen(s);
		n=(len+maxx-1)/maxx;
		int t=0,w=1;
		for(int i=0;i<len;i++)
		{
			w=w*10;
			if(i%maxx==0){w=1;++t;}
			a[t]=a[t]+w*(s[i]-'0');
		}
	}
	
	void Print()
	{
		if(f==-1)printf("-");
		printf("%d",a[n]);
		for(int i=n-1;i>0;i--)
		{
			printf("%04d",a[i]);
		}
	}
}p,q,ans;

Big operator-(const Big &p,const Big &q)
{
	Big c=p;
	for(int i=1;i<=c.n;i++)
	{
		c[i]=c[i]-q.a[i];
		if(c[i]<0)
		{

			c.a[i]=c.a[i]+digit;
			--c[i+1];
		}
	}
	while(c.n>0 && !c[c.n]) --c.n;
	return c;
}

void init()
{
	freopen("Lg P2142.in","r",stdin);
}

void readdata()
{
	scanf("%s\n%s",a,b);
}

void work()
{
	int lena=strlen(a),lenb=strlen(b);
	if(lenb>lena)
	{
		swap(a,b);
		f=-1;
	}
	if(f==1 && lenb==lena)
	{
		for(int i=lenb-1;i>=0;i--)
		{
			if(b[i]>a[i])
			{
				f=-1;
				swap(a,b);
				break;
			}
		}
	}
	reverse(a,a+strlen(a));
	reverse(b,b+strlen(b));	

	p=Big(a);
	q=Big(b);
	ans=p-q;
	ans.Print();
}
int main()
{
//	init();
	readdata();
	work();
	return 0;
}

乘法运算

Ai与Bi的乘积即为在【i+j-1】位上的值(满digit进位即可)

#include <bits/stdc++.h>
using namespace std;
const int maxn= 2005;
const int digit=10000;
const int maxx=4;


char a[maxn],b[maxn];

struct Big
{
	int a[maxn],n;
	Big(){n=1; memset(a,0,sizeof(a));}
	int& operator[](int x){return a[x];}
	
	Big(char *s)
	{
		memset(a,0,sizeof(a));
		int len=strlen(s);
		n=(len+maxx-1)/maxx;
		int t=0,w=1;
		for(int i=0;i<len;i++)
		{
			w=w*10;
			if(i%maxx==0){++t;w=1;}
			a[t]=a[t]+w*(s[i]-'0');
		}
	}
	void Print()
	{
		printf("%d",a[n]);
		for(int i=n-1;i>0;i--)
		{
			printf("%04d",a[i]);
		}
	}
}p,q,ans;

Big operator*(const Big &p,const Big &q)
{
	Big c;
	c.n=p.n+q.n-1;
	for(int i=1;i<=p.n;i++)
	{
		for(int j=1;j<=q.n;j++)
		{
			c[i+j-1]+=p.a[i]*q.a[j];
			c[i+j]+=(c[i+j-1])/digit;
			c[i+j-1]=c[i+j-1]%digit;
		}
	}
	if(c[c.n+1])++c.n;
	return c;
}


void init()
{
	freopen("Lg P1303.in","r",stdin);
}
void readdata()
{
	scanf("%s\n%s",a,b);
	reverse(a,a+strlen(a));
	reverse(b,b+strlen(b));
	p=Big(a);
	q=Big(b);
	ans=p*q;
	ans.Print();
}

int main()
{
//	init();
	readdata();
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值