大整数相加,相乘

 

    计算两个小的整形数相加的,用自带的+运算符就可以很容易的解决,但是对于两个很大的数来讲是会溢出的。用+运算符就无法完成了,当然你可以重载+运算符。

  其实对于两个大整数相加,就是用到我们小学时学加法的方法-------竖式加法,一位一位的去相加,相加的和大于9只要进一位就OK了。

代码如下:

#include <string.h>
#include <stdio.h>
const int N=100;
char s1[N],s2[N];  //保存输入的两个大整数
int bign1[N],bign2[N];  //把大整数转换成整数的形式

//把字符数字逆序转换成整数数字,
void char_num(char *s,int bin[]){
	int len=strlen (s);
	for (int i=len-1,k=0;i>=0;i--)
		bin[k++]=s[i]-'0';
}

//计算两个大整数的和
void _fun (int bin1[],int bin2[]){
	int i,j;
	for (i=0,j=0;i<N;i++,j++){
		bin1[i] += bin2[j];
		if (bin1[i] > 9){
			bin1[i] %= 10;
			bin1[i+1]++;
		}
	}
}
void print (int bin[]){
	bool flag=false;
	for (int i=N;i>=0;i--){
		if (flag)
			printf ("%d",bin[i]);
		else if (bin[i]){  //输出第一个非零的数。
			printf ("%d",bin[i]);
			flag=true;
		}
	}
	putchar ('\n');
}

///只能计算两个正的大整数相加
int main(){
	while (scanf ("%s%s",s1,s2)!=EOF){
		memset (bign1,0,sizeof (bign1));
		memset (bign2,0,sizeof (bign2));
		char_num (s1,bign1);
		char_num (s2,bign2);
		_fun (bign1,bign2);
		print (bign1);
	}
	return 0;
}

           现在考虑乘法,基本的思路都是一样的。

   现用usigned ans1[200]和usigned ans2[200]来保存两个乘数,用reault[400]来存放两个乘数的乘积。需说明一下,两个200位的数相乘,其积最大为400位的数。计算的过程和小学时的列竖式乘法基本相同,只不过编程方便把进位的步骤放在后面同一进行而已。

相以835x49为例进行说明:

1步:835x9    。5x9的得到45个1,3x9得到27个10,8x9得到72个100.由于不处理进位,所以结果为:

位数       3    2   1   0

-----0 0  0   72 27 45

接下来算4x5,得到20个10;故上述结果变为:

位数       3    2   1   0

-----0 0  0   72 47 45

再算4x3,得到12个100;故上述结果为:

位数       3    2   1   0

-----0 0  0   84 47 45

最后算4x8,得到32个1000;故上述结果为:

位数        3     2   1    0

-----0 0  32   84 47 45

自此,乘法已经算完了 。接下来处理进位的问题。

把realut[0]留下5,把4加到reault[1],得到51,把1留下,把5加到reault[2],得89.........

最后得到:

位数    4    3     2   1    0

----0    4    0     9    1    5

总结一个规律:一个数的第 i 位和另一个数的第 j 位相乘,一定是要累加到结果的第 i+j 位。(i ,j都是从0开始自右往左数)

代码如下:

#include <stdio.h>
#include <string.h>
const int N=200;
int len1,len2;

void char_num (char *s,unsigned bin[]){
	int len=strlen (s);
	for (int i=len-1,k=0;i>=0;i--)
		bin[k++]=s[i]-'0';
}
void _fun (unsigned bin1[],unsigned bin2[],unsigned ans[]){

	for (int i=0;i<len1;i++){
		for (int j=0;j<len2;j++)
			ans[i+j] += bin1[i]*bin2[j];  //两个数的  i j  位相乘 累加到结果的 i+j 位。
	}
}
void _carry (unsigned bin[]){
	int len=2*N;
	for (int i=0;i<len;i++){
		if (bin[i] > 9){
			bin[i+1] += bin[i] / 10;
			bin[i] %= 10;
		}
	}
}
void print (unsigned bin[]){
	bool flag=false;
	for (int i=N*2;i>=0;i--){
		if (flag)
			printf ("%d",bin[i]);
		else if (bin[i]){
			printf ("%d",bin[i]);
			flag=true;
		}
	}
	if (!flag)
		putchar ('0');  //和 0 相乘的情况。
	putchar ('\n');
}
int main (){
	
	unsigned ans1[N],ans2[N],reault[2*N+10];
	char s1[N],s2[N];

	while (scanf("%s%s",s1,s2)!=EOF){
		
		memset (ans1,0,sizeof (ans1));
		memset (ans2,0,sizeof (ans2));
		memset (reault,0,sizeof (reault));

		len1=strlen (s1),len2=strlen (s2);
		char_num (s1,ans1);
		char_num (s2,ans2);

		_fun (ans1,ans2,reault);
		_carry (reault);
		print (reault);
	}
	return 0;
}

可以看出,在处理完后进行进位,可能会更加方便点。

 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值