大数运算问题

C/C++编程中,过于大的两个数运算会存在溢出的问题,详细了解可看本博客此处。

那怎么运算特别大的数据而不越界溢出呢?以32位机器为例最大的数为0xFFFFFFFF。如果两个数运算如果大于这个数,则会回绕,超出32位的部分被截断,导致实际得到数远远小于想得到的数字。判断溢出的方法在溢出问题中已经详细说明了。

首先是计算一下两个不超出0xFFFFFFFF的值的平均值,面试的时候我的思路是对的,貌似面试官非得往大数运算上引导,这个程序算是开胃菜吧~

#include<stdio.h>
#include<limits.h>
#include<stdlib.h>
int unsigned_num_overflow(unsigned int var_a,unsigned int var_b)
{
	        unsigned int result;
			if(UINT_MAX-var_a < var_b)
				  return 1;
			else
			{
				result=var_a+var_b;
				printf("%#x\n",result);
			    return 0;
			}
}
int main()
{
      unsigned int var_c,var_d;
      var_c=0xfffffff2;
      var_d=0xfffffff4;

       if(unsigned_num_overflow(var_c>>1,var_d>>1))
	       printf("ungined overflow!!!\n");
}
这个程序,利用了溢出判断的条件,两个数都很大但是未超出范围。如果直接相加则可能引起回绕,然后高位被截断,得到的平均数并非为0xfffffff3,而是一个很小的数。这里我想到不相加,先对每个数字进行除以2的处理,这样再加起来必然不会超出范围,按照这个思路给unsigned_num_overflow函数传值是变量的一半,最后计算的结果是正确的0xfffffff3。

        那么如果进行相加怎么办呢?而且还要得到正确的结果,这里处理的时候就得使用字符串去处理,具体算法的实现过程,就是两个数以字符串传入,然后从第一个字符开始相加,存入一个整形数组,如果相加大于9,则数组的下一位加1,依次加完所有字符,然后从高到低依次输出所有数据,这个就是最终的需要的数值:
          

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define ARRLEN 10240

void add(char str1[],char str2[])
{
	int slen1=strlen(str1);
	int slen2=strlen(str2);

	int sum1[ARRLEN]={0},sum2[ARRLEN]={0},i=0,j;

	for(i=slen1-1,j=0;i>=0;i--)
	    sum1[j++]=str1[i]-'0';
	for(i=slen2-1,j=0;i>=0;i--)
		sum2[j++]=str2[i]-'0';

	for(j=0;j<ARRLEN;j++)
	{
		sum1[j]+=sum2[j];
		if(sum1[j]>9)
		{
			sum1[j]-=10;
			sum1[j+1]++;
		}
	}

	for(i=ARRLEN-1;(i>0)&&(sum1[i]==0);i--);
	if(i>=0)
	{
		while(i>=0)
		{
			printf("%d",sum1[i]);
			i--;
		}
	}
	else
		printf("0\n");
}
int main()
{
	printf("please input data:\n");
	char data1[ARRLEN],data2[ARRLEN];
	scanf("%[^\n]",data1);
	fflush(stdin);
	scanf("%[^\n]",data2);

	add(data1,data2);
}

你可能感兴趣的:(大数运算问题)