高精度计算踩坑记

Starluo 发布于 26 天前 1030 字 79 次阅读


规则怪谈:两个位数为$10^4$的整数相乘并不会得到一个$10^8$位数。

正如$\lg{ab} \neq \lg{a} \times \lg{b}$。

贴一个代码,该程序会输出$a+b、a-b、a*b、a/b、a\%b$的值。

优化什么的……以后再说吧!

#include<cstdio>
#include<cstring>
char a[10001],b[10001],cpy[10001],t;
int len,lena,lenb,pos,c[20001],aheadzero=0,bheadzero=0;
bool flag,big;
bool compare(char x[],char y[],int res,int jumphead)
{
	int xheadzero=0,yheadzero=0,lenx,leny;
	if(!jumphead)
	{
		for(int i=0;i<strlen(x);i++)
		{
			if(x[i]!='0') break;
			if(x[i]=='0') xheadzero=i+1;
		}
		if(xheadzero)
		{
			lenx=strlen(x);
			for(int i=xheadzero;i<lenx;i++) x[i-xheadzero]=x[i];
			for(int i=lenx-xheadzero;i<lenx;i++) x[i]=0;
		}
		for(int i=0;i<strlen(y);i++)
		{
			if(y[i]!='0') break;
			if(y[i]=='0') yheadzero=i+1;
		}
		if(yheadzero)
		{
			leny=strlen(y);
			for(int i=yheadzero;i<leny;i++) y[i-yheadzero]=y[i];
			for(int i=leny-yheadzero;i<leny;i++) y[i]=0;
		}
	}
	lenx=strlen(x),leny=strlen(y);
	if(lenx>leny) return true;
	if(lenx<leny) return false;
	if(res)
	{
		for(int i=lenx-1;i>=0;i--)
		{
			if(x[i]==y[i]) continue;
			if(x[i]<y[i]) return false;
			else return true;
		}
	}
	else
	{
		for(int i=0;i<lenx;i++)
		{
			if(x[i]==y[i]) continue;
			if(x[i]<y[i]) return false;
			else return true;
		}
	}
	return true;
}
int main()
{
	scanf("%s%s",a,b);
	for(int i=0;i<strlen(a);i++)
	{
		if(a[i]!='0') break;
		if(a[i]=='0') aheadzero=i+1;
	}
	if(aheadzero)
	{
		len=strlen(a);
		for(int i=aheadzero;i<len;i++) a[i-aheadzero]=a[i];
		for(int i=len-aheadzero;i<len;i++) a[i]=0;
	}
	for(int i=0;i<strlen(b);i++)
	{
		if(b[i]!='0') break;
		if(b[i]=='0') bheadzero=i+1;
	}
	if(bheadzero)
	{
		len=strlen(b);
		for(int i=bheadzero;i<len;i++) b[i-bheadzero]=b[i];
		for(int i=len-bheadzero;i<len;i++) b[i]=0;
	}
	lena=strlen(a),lenb=strlen(b);
	len=(lena>lenb?lena:lenb);
	for(int i=0;i<lena/2;i++) t=a[i],a[i]=a[lena-i-1],a[lena-i-1]=t;
	for(int i=0;i<lenb/2;i++) t=b[i],b[i]=b[lenb-i-1],b[lenb-i-1]=t;
	for(int i=0;i<len;i++)
	{
		c[i+1]+=((a[i]>'0'?a[i]-'0':0)+(b[i]>'0'?b[i]-'0':0)+c[i])/10;
		c[i]=((a[i]>'0'?a[i]-'0':0)+(b[i]>'0'?b[i]-'0':0)+c[i])%10;
	}
	flag=true;
	for(int i=len+1;i>=0;i--)
	{
		if(!c[i]&&flag) continue;
		printf("%d",c[i]);
		flag=false;
	}
	printf("\n");
	memset(c,0,sizeof(c));
	big=compare(a,b,0,1);
	if(!big) printf("-"); 
	for(int i=0;i<len;i++)
	{
		c[i]+=(big?((a[i]>'0'?a[i]-'0':0)-(b[i]>'0'?b[i]-'0':0)):((b[i]>'0'?b[i]-'0':0)-(a[i]>'0'?a[i]-'0':0)));
		if(c[i]<0) c[i]+=10,c[i+1]--;
	}
	flag=true;
	for(int i=len;i>=0;i--)
	{
		if(!c[i]&&flag&&i) continue;
		printf("%d",c[i]);
		flag=false;
	}
	memset(c,0,sizeof(c));
	printf("\n");
	for(int i=0;i<lena;i++)
	{
		for(int j=0;j<lenb;j++)
		{
			c[i+j+1]+=((a[i]>'0'?a[i]-'0':0)*(b[j]>'0'?b[j]-'0':0)+c[i+j])/10;
			c[i+j]=((a[i]>'0'?a[i]-'0':0)*(b[j]>'0'?b[j]-'0':0)+c[i+j])%10;
		}
	}
	flag=true;
	for(int i=lena+lenb;i>=0;i--)
	{
		if(!c[i]&&flag&&i) continue;
		printf("%d",c[i]);
		flag=false;
	}
	memset(c,0,sizeof(c));
	printf("\n");
	if(!big)
	{
		printf("0\n");
		for(int i=lena-1;i>=0;i--) printf("%c",a[i]);
		return 0;
	}
	for(int i=0;i<lena/2;i++) t=a[i],a[i]=a[lena-i-1],a[lena-i-1]=t;
	for(int i=0;i<lenb/2;i++) t=b[i],b[i]=b[lenb-i-1],b[lenb-i-1]=t;
	pos=-1;
	for(int i=lenb-1;i<lena;i++)
	{
		strncpy(cpy,a,i+1);
		pos++;
		while(compare(cpy,b,0,0))
		{
			for(int j=lenb-1;j>=0;j--)
			{
				a[i-(lenb-1-j)]-=b[j];
				a[i-(lenb-1-j)]+='0';
				if(a[i-(lenb-1-j)]<'0') a[i-(lenb-1-j)]+=10,a[i-(lenb-1-j)-1]--;
			}
			c[pos]++;
			strncpy(cpy,a,i+1);
		}
	}
	if(pos<0) pos=0;
	flag=true;
	for(int i=0;i<=pos;i++)
	{
		if(!c[i]&&flag&&i!=pos) continue;
		printf("%d",c[i]);
		flag=false;
	}
	printf("\n");
	flag=true;
	for(int i=0;i<lena;i++)
	{
		if(a[i]=='0'&&flag&&i!=lena-1) continue;
		printf("%c",a[i]);
		flag=false;
	}
	return 0;
}
此作者没有提供个人介绍。
最后更新于 2025-08-15