c蓝桥杯P1001精确运算

当两个比较大的整数相乘时,可能会出现数据溢出的情形。为避免溢出,可以采用字符串的方法来实现两个大数之间的乘法。具体来说,首先以字符串的形式输入两个整数,每个整数的长度不会超过8位,然后把它们相乘的结果存储在另一个字符串当中(长度不会超过16位),最后把这个字符串打印出来。例如,假设用户输入为:62773417和12345678,则输出结果为:774980393241726.

输入:
  62773417 12345678

输出:

  774980393241726

本题思路就是模拟手算过程。

#include<stdio.h>   /*try_fei_ge*/
#include<math.h>
#include<string.h>
void up(char c[],int cur);     /*进位*/
int main()
{
	int i,j,k,l,j_wei,j_cur,i_wei,number;
	char ch='+',a[16],b[16],c[100000];
	memset(c,0,sizeof(c));
	scanf("%s %s",a,b);
	i=strlen(a)-1;
	j=strlen(b)-1;
	if(a[0]=='-')   /*判断数a是否为负数若是记录下负号并且将其余元素前移*/
	{
		ch='-';
		for(k=0;k<=i;k++)
			a[k]=a[k+1];
	}
	if(b[0]=='-')
	{
		if(ch=='-')	ch='+';
		else ch='-';
		for(k=0;k<=j;k++)
			b[k]=b[k+1];
	}
	for(k=0;k<=i;k++)     /*将字符一转化为ascll码表示,避免计算时超过127*/
		a[k]=a[k]-'0';
	for(l=0;l<=j;l++)
		b[l]=b[l]-'0';
	for(i_wei=0;i>=0;i--,i_wei++)   /*从数a最低位开始运算*/
	{
		for(j_wei=0,j_cur=j;j_cur>=0;j_cur--,j_wei++)  /*使数b每一位与数a相乘并将结果相加*/
		{
			number=a[i]*b[j_cur];        /*将两数相乘结果暂时放置一位中*/
			c[i_wei+j_wei]=c[i_wei+j_wei]+number;/*注意此处下标与当前数是十的几倍有关!*/
			up(c,i_wei+j_wei);   /*判断该位是否大于10需要进位*/
		}
	}
	for(i=99999;c[i]==0&&i>=0;i--) ;/*运算时逆序保存,找到最高位*/
	if(ch=='-')	printf("-"); /*如果为负数输出负号*/
	if(i==-1)	putchar('0');  /*如果遍历到数组0处任未找到数则为0*/
	else for(;i>=0;i--)   /*输出数*/
			printf("%c",c[i]+'0');/*开始时ascll码缩小至0~9,现在扩大回去*/
	return 0;
} 
void up(char c[],int cur)
{
	int ch;
	if((ch=c[cur])>=10)/*当前位小于0不在进位*/
	{
		c[cur]=(ch%10);
		c[cur+1]=c[cur+1]+(ch/10);
		up(c,cur+1);    /*递归判断当前进位后下一位是否需要进位*/
	}
}

version 2.0

#include<stdio.h>  /*try_fei_ge*/
#include<string.h>
void carry(char c[],int cur);
int main(
{
	int la,lb;
	int start = 399,offest = 0;
	char a[200],b[200],c[400];
	memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(c,0,sizeof(c));
	scanf("%s",a);
	scanf("%s",b);
	la = strlen(a);
	lb = strlen(b);
	--la;--lb;
	if(la == 0 && a[la] == '0')	{printf("0");return 0;}
	if(lb == 0 && b[lb] == '0')	{printf("0");return 0;}
	for(int cur_a = la;cur_a >= 0;cur_a--)
		for(int cur_b = lb;cur_b >= 0;cur_b--)
		{
			 int cur = start - (lb - cur_b) - (la - cur_a);
			 c[cur] += (b[cur_b] - '0') * (a[cur_a] - '0');
			 carry(c,cur);
		}
	int i = 0;
	for(;i <= start;i++)
		if(c[i] != 0)
			break;
	for(;i <= start;i++)
		printf("%d",c[i]);
	return 0;
 } 
void carry(char c[],int cur)
{
	if(c[cur] >= 10)
	{
		c[cur-1] += c[cur] / 10;
		c[cur] = c[cur] % 10;
		carry(c,cur-1);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值