大数运算(加、减、乘)

  • Post author:
  • Post category:其他


计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组 A 来表示一个大整数 a,A[0]表示 a 的个位,A[1]表示 a 的十位,依次类推。然后只需要处理数组中的每一位的数据。



大数运算



加法



代码



思路

遍历数组c中每一个数据,如果大于9,则需要执行进位操作

c[j]=c[j]-10;
c[j+1]=c[j+1]+1;

最后将c中储存的结果倒序输出就行了。



减法



代码

#include<stdio.h>
#include<math.h>
int dx(int aq,int bq)
{
	int a;
	if(aq==bq){
		a=0;        //减数和被减数大小相等 
	}
	if(aq>bq){
		a=1;        //被减数大于减数 
	}
	if(aq<bq){
		a=2;        //减数大于被减数 
	}
	return a;
}
int main()
{
 	int aq=0,bq=0,ax,bx;
	int a[8]={5,3,4,8,8,4,2,8},b[8]+{1,3,5,4,7,3,9,4},c[20];
	for(int j=0;j<20;j++)
	{
		c[j]=9999;
	}

	for(int j=0;j<8;j++)     //用加权的方法判断数组a和数组b那个大 
	{
		if(a[j]>b[j])
		{
			ax=int(pow(2,j));
			aq=aq+ax;
		}
		if(b[j]>a[j])
		{
			bx=int(pow(2,j));
			bq=bq+bx;
		}	
	}
	if(dx(aq,bq)==0){
		printf("0");    //两数相等直接输出0 
	}
	if(dx(aq,bq)==1){
		for(int j=0;j<8;j++)
		{
			c[j]=a[j]-b[j];
		}
	}
	if(dx(aq,bq)==2){
		for(int j=0;j<8;j++)
		{
			c[j]=b[j]-a[j];
		}
	}
	for(int j=0;j<20;j++){      //遍历数组c,将其中的负数变成整数,且后一位减一,模拟“借数” 
		if(c[j]<0)
		{
			c[j]=c[j]+10;
			c[j+1]=c[j+1]-1;
		}
	}

	if(dx(aq,bq)==2){
		printf("-");
	}
	for(int j=19;j>=0;j--)
	{
		if(c[j]>=0&&c[j]!=9999)
		{
			printf("%d",c[j]);
		}
	}
	return 0;
}



思路

在定义数组a和b时,有几个数据就定义多大的数组。

1.先用加权的方法判断a(被减数)和b(减数)里储存的数的大小,若b>a,则a与b调换位置,用b去减a,在输出最终结果是带上负号。

2.拿被减数的每一个去减对应下标的减数,并且把结果存储到对应下标的c数组中。

3.遍历检查c数组,若出现小于0的数,则模拟借位的操作。

c[j]=c[j]+10;
c[j+1]=c[j+1]-1;

4.将c中储存的结果倒序输出就行了。



乘法



代码

#include<stdio.h>
int main()
{
	int a[8]={0,9,1},b[8]={0,4,5},c[7]={0},z[3][6]={0};
	int n,m,r=0;
	n=3;                  //n=乘数的位数,m=2n,数组c的大小=m+1;
	m=2*n;
	for(int j=0;j<n;j++)    //初始化数组z
	{
		for(int i=0;i<m;i++)
		{
			z[j][i]=-2;
		}
	} 
	for(int j=1;j<n;j++)  //模拟错位
	{
		for(int i=0;i<j;i++)
		{
			z[j][i]=-1;
		}
	} 
	for(int j=0;j<n;j++)   //相乘
	{
		for(int i=0;i<n;i++)
		{
			for(int u=0;u<6;u++)
			{
				if(z[j][u]==-2){
					z[j][u]=a[j]*b[i];
					break;
				}
			}
		}	
	}
	for(int j=0;j<n;j++)    //处理数组z中的数据
	{
		for(int i=0;i<m;i++)
		{
			if(z[j][i]>9)
			{
				if(z[j][i+1]==-2){
					z[j][i+1]=z[j][i+1]+(z[j][i]/10)+2;
				}
				else{
					z[j][i+1]=z[j][i+1]+(z[j][i]/10);
				}
				z[j][i]=z[j][i]%10;
			}
		}	
	}
	for(int j=0;j<n;j++)    //替换数组z中的-1和-2,为下一步做准备
	{
		for(int i=0;i<m;i++)
		{
			if(z[j][i]==-2||z[j][i]==-1)
			{
				z[j][i]=0;
			}
		}
	}
	for(int j=0;j<n;j++)     //用数组c加数组z的每一行
	{
		for(int i=0;i<m;i++)
		{
			c[i]=c[i]+z[j][i]; 
		}
	}
	for(int j=0;j<m+1;j++)   //模拟加法进位
	{
		if(c[j]>9)
		{
			c[j+1]=c[j+1]+(c[j]/10);
			c[j]=c[j]%10;
		}
	}
	for(int j=6;j>=0;j--)     //优化输出,记录结果前面的0的个数
	{
		if(c[j]==0)
		{
			r++;
		}
		else{
			break;
		}
	}
	for(int j=m-r;j>=0;j--)  //倒序输出
	{
		printf("%d",c[j]); 
	}
	return 0;
}



思路

1.依据乘数的位数创建数组,n等于乘数的位数,m等于2n,数组c的大小等于m+1,创建二维数组,

a[n][m],c[m+1]

2.因为在我们手算乘法时,每一位数乘以被乘数需要产生错位,因此我们需要进行模拟错位。就像下面把一部分-2规律的替换成-1,在进行相乘是用于区分。

-2 -2 -2 -2 -2
-1 -2 -2 -2 -2
-1 -1 -2 -2 -2
-1 -1 -1 -2 -2

3.将数组a中的每一位分别乘数组b中的每一位,将结果存在数组z中。只有数组z的位置是-2才可以存入,不然在同一行中向后判断是否可以存入。

4.整理数组z中的数据,遍历数组z的每一行,若z[j]大于9,则在同一行的后面一个数加上z[j]的十位,z[j]变为z[j]的个位。

如:12 ,3 ,6 ——> 2 ,4 ,6

5.将数组z中所有的负数替换成0,让数组c去加数组z中的每一行,再将数组c中的数据模拟进位操作。

6.倒序输出数组c。

这时会出现一个小错误,输出的结果前面会多输出几个0,用一个变量记录一下有几个0,然后优化一下输出就行了。

-2才可以存入,不然在同一行中向后判断是否可以存入。

4.整理数组z中的数据,遍历数组z的每一行,若z[j]大于9,则在同一行的后面一个数加上z[j]的十位,z[j]变为z[j]的个位。

如:12 ,3 ,6 ——> 2 ,4 ,6

5.将数组z中所有的负数替换成0,让数组c去加数组z中的每一行,再将数组c中的数据模拟进位操作。

6.倒序输出数组c。

这时会出现一个小错误,输出的结果前面会多输出几个0,用一个变量记录一下有几个0,然后优化一下输出就行了。



版权声明:本文为weixin_54165588原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。