专题 高精度算法

时间:2019-04-19
本文章向大家介绍专题 高精度算法,主要包括专题 高精度算法使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

算法简介

高精度算法,属于处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字。一般这类数字我们统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算。对于非常庞大的数字在C++中正常存储, 看看人家Java和python ,于是,将这个数字拆开,拆成一位一位的,或者是四位四位的存储到一个数组中, 用一个数组去表示一个数字,这样这个数字就被称为是高精度数。高精度算法就是能处理高精度数各种运算的算法,但又因其特殊性,故从普通数的算法中分离,自成一家。

这里,我们给出相对较快的压位的高精度模板。因为理解起来十分容易,这里不做过多的说明。

同时,网上两位不知名的大佬的模板给了我很大的帮助:
https://www.cnblogs.com/hnqw1214/p/6351321.html
https://www.cnblogs.com/candy99/p/gaojingdu.html

【代码】

#include <bits/stdc++.h>
using namespace std;

const int Mod=10000;
const int power=4;
char str1[10010],str2[10010];

struct Big
{
	int a[50000],n;
	int& operator [](int x) {return a[x];}
	Big():n(1) {memset(a,0,sizeof(a));}
	Big(char *str)
	{
		int len=strlen(str),w,t=0;
    	reverse(str,str+len);
    	n=(len+power-1)/power;
    	for(int i=0;i<len;++i)
    	{
    		if(i%power==0) {w=1; ++t;}
    		a[t]+=w*(str[i]-'0');
    		w*=10;
    	}
	}
	void init(int x) {a[1]=x; n=1;}
};

bool operator <(Big a,Big b) //小于 
{
	if(a.n==a.n)
	{
		for(int i=a.n;i>=1;i--)
		{
			if(a[i]==b[i]) continue;
			else return a[i]<b[i];
		}
	}
	else return a.n<b.n;
}

Big operator +(Big a,Big b) //加法
{
	int g=0,n=max(a.n,b.n);
	for(int i=1;i<=n;++i)
	{
		g+=(i<=a.n?a[i]:0);
		g+=(i<=b.n?b[i]:0);
		a[i]=g%Mod; g/=Mod;
	}
	a.n=n;
	if(g) a[++a.n]=g;
	return a;
}

Big operator -(Big a,Big b) //减法
{
	bool flag=0;
    if(a<b) {flag=1; swap(a,b);} //如果a<b,减法运算之后就是负数,所以交换后会很方便 
    for(int i=1;i<=b.n;i++)
    {
    	if(a[i]<b[i]) {a[i]+=Mod; a[i+1]--;}
    	a[i]-=b[i];
	}
	while(a[a.n]==0&&a.n) a.n--;
    if(flag) a[a.n]=-a[a.n];
    return a;
}

Big operator *(Big a,Big b) //乘法 
{
	Big c;
	for(int i=1;i<=a.n;++i)
	{
		int g=0;
		for(int j=1;j<=b.n;++j)
		{
			g+=c[i+j-1]+a[i]*b[j];
			c[i+j-1]=g%Mod; g/=Mod;
		}
		c[i+b.n]=g;
	}
	c.n=a.n+b.n;
	while(c.n&&c[c.n]==0) c.n--;
	return c;
}

void Print(Big a) //输出 
{
	printf("%d",a[a.n]);
	for(int i=a.n-1;i>=1;i--)
	    printf("%04d",a[i]);
}

int main()
{
//	freopen("input.txt","r",stdin);
//	freopen("output.txt","w",stdout);
	scanf("%s%s",str1,str2);
	Big a=Big(str1),b=Big(str2);
	Print(a+b); putchar('\n');
	Print(a-b); putchar('\n');
	Print(a*b); putchar('\n');
	return 0;
}