大数相加 相乘

  用字符串保存两个大数。 把加法分解成: 一,同一位上为 (a+b)%10 二,进位(a+b)/10 ,三,把第一数+进位
感觉是递归了。但可以用循环在代替。
  大数相乘也差不多,第二数的每一位数都与第一个数每一位相乘,然后相加起来.
以下我们假设两个字符串里都是数字,之里不做判断了.
为了解题方便,我还把数字都移到数组的右端,方便相加.不足是会浪费一些时间
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 20
//判断 字符串中是否全是0
int isZero(const char* s)
{
	if (s == NULL || s == '\0')
		return 1;
	while (*s != '\0')
	{
		if (*s++ != '0')
			return 0;
	}
	return 1;
}
//假设len >= strlen(src)+1
//把src中的字符串把到dest的右端,前面补0
char* rcpy_addZero(char *dest, int len, const char *src)
{
	int i, srcLen = 0;
	if (src == NULL)
		srcLen = 0;
	else
		srcLen = strlen(src);
	if(len < srcLen+1) return NULL;
	dest[len - 1] = '\0';
	for (i = 0; i < len - srcLen - 1; i++)
	{
		dest[i] = '0';
	}
	strncpy(dest + len - srcLen - 1, src, srcLen);
	return dest;
}
//我们假设两个数都不会超过MAXSIZE-2位(两数组的长度不超过MAXSIZE-1),ps:最后一位用来放'\0',第一位用来放 进位
//只限两个正整数
char* bigNumAdd(const char* a, const char *b,char *result)
{
	//s1的长度更大
	char s1[MAXSIZE],s2[MAXSIZE];
	int i,s;
	if (a == NULL && b == NULL)
		return NULL;
	//pSum = (char *) malloc(sizeof(char) * MAXSIZE);
	/************kit start************/
	rcpy_addZero(s1,MAXSIZE,a);
	rcpy_addZero(s2,MAXSIZE,b);
	while (isZero(s2)==0)
	{
		for (i=0;i<MAXSIZE-1;i++)
		{
			s = s1[i] + s2[i] - '0' - '0';
			if (s > 9)
			{
				s1[i] = s - 10 + '0';
				i && (s2[i-1]='1'); // i=0时 ,不进位
			}
			else
			{
				s1[i] = s + '0';
				i && (s2[i-1]='0');
			}
		}
		s2[i-1]='0';
	}
	strcpy(result,s1);
	return result;
}
//左移n位,补0
void LeftShift(char* s,int n)
{
	if(s==NULL) return;
	int i=0;
	int len=strlen(s);
	for(i=n;i<len;i++)
	{
		s[i-n]=s[i];
	}
	for(i=0;i<n;i++)
	{
		s[len-1-i]='0';
	}
}
//大数相乘 两个字符串必须为整数
char *bigNumsMultiply(const char *a,const char *b,char *result)
{
	int isNegative=0,i,k,s;
	char s1[MAXSIZE],s2[MAXSIZE],sum[MAXSIZE],carry[MAXSIZE];
	carry[MAXSIZE-2]='0';
	if(a==NULL ||  b==NULL) return NULL;
	if(a[0] == '+' || a[0] == '-' || b[0] == '+' || b[0] == '-')
	{
		if((a[0]=='-' || b[0]=='-') && a[0]!=b[0])  isNegative=1;
	}
	if (a[0] == '+' || a[0] == '-')		rcpy_addZero(s1, MAXSIZE, a + 1);
	else								rcpy_addZero(s1, MAXSIZE, a );
	if (b[0] == '+' || b[0] == '-')		rcpy_addZero(s2, MAXSIZE, b + 1);
	else								rcpy_addZero(s2, MAXSIZE, b);
	result[0] = '\0';
	carry[MAXSIZE - 2] = '0';
	carry[MAXSIZE - 1] = '\0';
	for(i=MAXSIZE-2;i>=0;i--) //s2
	{
		for(k=MAXSIZE-2;k>=0;k--) //s1
		{
			s=(s1[k]-'0')*(s2[i]-'0');
			sum[k]=s%10 + '0';
			k && (carry[k-1]=s/10 + '0'); //防止最高位进位
		}
		bigNumAdd(sum,carry,sum);
		bigNumAdd(sum,result,result);
		LeftShift(s1,1); //左移一位
	}
	if(isNegative) result[0]='-';
	return result;
}
int main(void)
{
	char pSum[MAXSIZE];
	printf("Add:%s\n",bigNumAdd("87968645654213","5645461359",pSum));
	printf("Mutiply:%s",bigNumsMultiply("-1232424465","-4566228",pSum));
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值