大整数的加减乘除

/*大整数运算*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100

char* add(char* a,char* b);
char* sub(char* a,char* b);
char* mul(char* a,char* b);
char* div(char* a,char* b);
bool isValid(char* a,int n);
char* add_core(char* a,char* b);
char* sub_core(char* a,char* b);
char* mul_core(char* a,char* b);
char* div_core(char* a,char* b);
int main()
{
	char* a;
	char* b;
	a=(char*)malloc(sizeof(char)*MAX);
	b=(char*)malloc(sizeof(char)*MAX);
	scanf("%s",a);
	scanf("%s",b);
	if(isValid(a,strlen(a)) && isValid(b,strlen(b)))
	{
		printf("a+b=%s\n",add(a,b));
		//add(a,b);
		printf("a-b=%s\n",sub(a,b));
		printf("a*b=%s\n",mul(a,b));
		printf("a/b=%s\n",div(a,b));
	}
	else
	{
		printf("invalid input\n");
	}
	return 0;
}
bool isValid(char* a,int n)
{
    int i;

	if(a==NULL || n<=0)
		return false;
	if(!(a[0]=='-' || (a[0]>='0' && a[0]<='9')))
		return false;
	if(a[0]=='0' && a[1]!='\0')
		return false;
	for(i=1;i<n;i++)
		if(a[i]<'0' || a[i]>'9')
			return false;
	return true;
}
char* add(char* a,char* b)
{
	int len1=strlen(a);
	int len2=strlen(b);
	int len=len1>len2?len1:len2;
	char* c;
	c=(char*)malloc(sizeof(char)*(len+3));
    if(a[0]!='-' && b[0]!='-')//a+b
	{
		return add_core(a,b);
	}
	else if(a[0]=='-' && b[0]=='-')//-a-b
	{
		c[0]='-';
		c[1]='\0';
		strcat(c,add_core(a+1,b+1));
        return c;
	}
	else if(a[0]=='-' && b[0]!='-')//-a+b
	{
		return sub(b,a+1);
	}
	else if(a[0]!='-' && b[0]=='-')//a-b
	{
		return sub(a,b+1);
	}
}
char* add_core(char* a,char* b)
{
	int len1=strlen(a);
	int len2=strlen(b);
	int len=len1>len2?len1+1:len2+1;
	char* c;
	int i=len-1,carry=0,temp;
	int index1=len1-1,index2=len2-1;
	c=(char*)malloc(sizeof(char)*(len+1));
	c[len]='\0';
    while(index1>=0 && index2>=0)
	{
		temp= a[index1--]-'0' + b[index2--]-'0' + carry;
		if(temp>=10)
		{
			carry=1;
			c[i--]=temp-10+'0';
		}
		else 
		{
		    carry=0;
			c[i--]=temp+'0';
		}
	}
	while(index1>=0)
	{
		temp= a[index1--]-'0'+carry;
		if(temp>=10)
		{
			carry=1;
			c[i--]=temp-10+'0';
		}
		else 
		{
		    carry=0;
			c[i--]=temp+'0';
		}
	}
    while(index2>=0)
	{
		temp= b[index2--]-'0'+carry;
		if(temp>=10)
		{
			carry=1;
			c[i--]=temp-10+'0';
		}
		else 
		{
		    carry=0;
			c[i--]=temp+'0';
		}
	}
	c[i]=carry+'0';
	i=0;
	while(c[i]=='0')
		i++;
    return c+i;
}
char* sub(char* a,char* b)
{
	int len1=strlen(a);
	int len2=strlen(b);
	int len=len1>len2?len1:len2;
	char* c;
	c=(char*)malloc(sizeof(char)*(len+2));
	if(a[0]!='-' && b[0]!='-')//a-b
	{
		if(len1>len2 || (len1==len2 && strcmp(a,b)>0))
			return sub_core(a,b);
		else if(len1<len2 || (len1==len2 && strcmp(a,b)<0))
		{
			c[0]='-';
			c[1]='\0';
			strcat(c,sub_core(b,a));
			return c;
		}
		else if(strcmp(a,b)==0)
		{
			c[0]='0';
			c[1]='\0';
			return c;
		}
	}
	else if(a[0]=='-' && b[0]=='-')//-a+b
	{
		if(len1<len2 || (len1==len2 && strcmp(a+1,b+1)<0))
			return sub_core(b+1,a+1);
		else if(len1>len2 || (len1==len2 && strcmp(a+1,b+1)>0))
		{
			c[0]='-';
			c[1]='\0';
			strcat(c,sub_core(a+1,b+1));
			return c;
		}
		else if(strcmp(a+1,b+1)==0)
		{
			c[0]='0';
			c[1]='\0';
			return c;
		}
	}
	else if(a[0]=='-' && b[0]!='-')//-a-b
	{
		c[0]='-';
		c[1]='\0';
		strcat(c,add_core(a+1,b));
		return c;
	}
	else if(a[0]!='-' && b[0]=='-')//a+b
	{
		return add_core(a,b+1);
	}
}
char* sub_core(char* a,char* b)
{
	int len1=strlen(a);
	int len2=strlen(b);
	int len=len1>len2?len1:len2;
	char* c;
	int index1=len1-1,index2=len2-1,index=len-1;
	int temp,carry=0;
	c=(char*)malloc(sizeof(char)*(len+1));
	c[len]='\0';
	while(index1>=0 && index2>=0)
	{
		temp=(a[index1--]-'0')-(b[index2--]-'0')-carry;
		if(temp<0)
		{
			temp=10+temp;
			carry=1;
			c[index--]=temp+'0';
		}
		else
		{
			carry=0;
			c[index--]=temp+'0';
		}
	}
    while(index1>=0)
	{
		temp=(a[index1--]-'0')-carry;
		if(temp<0)
		{
			temp=10+temp;
			carry=1;
			c[index--]=temp+'0';
		}
		else
		{
			carry=0;
			c[index--]=temp+'0';
		}
	}
	index=0;
	while(c[index]=='0')
		index++;
	return c+index;

}
char* mul(char* a,char* b)
{
	int len1=strlen(a);
	int len2=strlen(b);
	int len=len1+len2;
	char* c;
	c=(char*)malloc(sizeof(char)*(len+1));
	if(a[0]=='-' && b[0]=='-')
	{
		return mul_core(a+1,b+1);
	}
    if(a[0]=='-' && b[0]!='-')
	{
		c[0]='-';
		c[1]='\0';
		strcat(c,mul_core(a+1,b));
		return c;
	}
	if(a[0]!='-' && b[0]=='-')
	{
		c[0]='-';
		c[1]='\0';
		strcat(c,mul_core(a,b+1));
		return c;
	}
	if(a[0]!='-' && b[0]!='-')
	{
		return mul_core(a,b);
	}
}
char* mul_core(char* a,char* b)
{
    int len1=strlen(a);
	int len2=strlen(b);
	int len=len1+len2;
	char* c;
	int index1,index2,index;
	int temp,carry=0;
	
	c=(char*)malloc(sizeof(char)*(len+1));
	c[len]='\0';
	for(index=0;index<len;index++)
		c[index]='0';
	for(index2=len2-1;index2>=0;index2--)
	{
		for(index1=len1-1;index1>=0;index1--)
		{
			c[index1+index2+1]=(a[index1]-'0')*(b[index2]-'0')+c[index1+index2+1];
		}
	}
	for(index=len-1;index>=0;index--)
	{
		temp=c[index]-'0'+carry;
		if(temp>=10)
		{
			carry=temp/10;
			c[index]=temp%10+'0';
		}
		else
		{
			carry=0;
			c[index]=temp+'0';
		}
	}
	index=0;
	while(c[index]=='0')
		index++;
	if(index==len)
		return c+index-1;
	return c+index;
}
char* div(char* a,char* b)
{
	int len1=strlen(a);
	int len2=strlen(b);
	int len=len1-len2+2>2?len1-len2+2:2;
	char* c;
	char* temp1;
	char* temp2;
	c=(char*)malloc(sizeof(char)*(len+1));
	temp1=a;
	temp2=b;
	if(a[0]=='-')
		temp1=a+1;
	if(b[0]=='-')
		temp2=b+1;

    c[0]='0';
	c[1]='\0';
	if(strlen(temp1)<strlen(temp2) || (strlen(temp1)==strlen(temp2) && strcmp(temp1,temp2)<0))
		return c;
    if(strcmp(b,c)==0)
		return NULL;

	if(a[0]=='-' && b[0]=='-')
		return div_core(a+1,b+1);
	if(a[0]=='-' && b[0]!='-')
	{
		c[0]='-';
		c[1]='\0';
		strcat(c,div_core(a+1,b));
		return c;
	}
	if(a[0]!='-' && b[0]=='-')
	{
		c[0]='-';
		c[1]='\0';
		strcat(c,div_core(a,b+1));
		return c;
	}
	if(a[0]!='-' && b[0]!='-')
	{
		return div_core(a,b);
	}
}
char* div_core(char* a,char* b)
{
	int len1=strlen(a);
	int len2=strlen(b);
	int len=len1-len2+2;
	int div_len=0;

	int index1=0;
	int index=0;
	char* c;
	char* div;
	char* pc;
	c=(char*)malloc(sizeof(char)*(len+1));
	div=(char*)malloc(sizeof(char)*(len2+2));
	pc=(char*)malloc(sizeof(char)*(len2+1));
	//div="";
    for(index=0;index<len;index++)
		c[index]='0';
	index=0;
	while(index1<len1)
	{
		while(div_len<len2 || (div_len==len2 && strcmp(div,b)<0))
		{
			//div_len=strlen(div);
			div[div_len]=a[index1++];
			div[div_len+1]='\0';
			div_len=strlen(div);
		}
		while(1)
		{
			pc=sub_core(div,b);
			if(strlen(pc)>len2 || (strlen(pc)==len2 && strcmp(pc,b)>0))
			    c[index]++;
			
			else 
				break;	
			strcpy(div,pc);
		}
		c[index]++;
		index++;
		
	}
	c[index]='\0';
	return c;
}

### 大整数加减乘除运算实现方法 #### 一、大整数表示 对于大整数而言,单个机器字无法容纳其全部数值范围。因此,在编程中通常采用数组或者链表来存储每一位上的数字[^2]。 #### 二、加法运算 当执行两个正向的大整数相加操作时,可以逐位累加对应位置上的值,并记录进位情况直到最高位为止。而对于涉及负数的情况,则需先转换成绝对值形式做上述相同的操作后再依据原始符号决定最终结果的正负号[^3]。 ```cpp // 假设 num1 和 num2 是两个长度相同的字符串类型的正整数 string add(const string& num1, const string& num2){ int carry = 0; string result; reverse(num1.begin(),num1.end()); reverse(num2.begin(),num2.end()); for (size_t i = 0; i<num1.size() || i<num2.size(); ++i) { int sum = carry + (i<num1.size()?num1[i]-'0':0)+(i<num2.size()?num2[i]-'0':0); if(sum >= 10){ carry = 1; sum -= 10; }else{ carry = 0; } result.push_back('0'+sum); } if(carry>0) result.push_back('1'); reverse(result.begin(),result.end()); return result; } ``` #### 三、减法运算 同样地,针对两者的差分计算也需要考虑借位逻辑以及可能出现的结果为零的情形。特别注意的是,如果被减数小于减数的话应该交换两者顺序并标记结果应取相反数。 ```cpp bool isGreaterThanOrEqual(string a,string b){...}// 判断函数略过 string subtract(const string &minuend,const string &subtrahend,bool *sign){ bool flag=false; if(!isGreaterThanOrEqual(minuend, subtrahend)){ swap(minuend,subtrahend); flag=true; } ... (*sign)=flag; return difference_string; } ``` #### 四、乘法运算 通过模拟手工竖式乘法规则来进行多位数之间的相互作用。即遍历每一个因子的位置并与另一个因子里的所有元素依次相乘得到部分积之后再把这些临时产物按照相应权重叠加起来形成总的乘积累计值[^4]。 ```cpp string multiply(string A , string B ) { ... }//具体实现在此省略 ``` #### 五、除法运算 利用试商的方法逐步逼近正确的商值直至余数不足以继续分割为止。这里需要注意处理好每次试探过程中产生的新余项更新问题还有防止溢出的风险控制措施。 ```cpp pair<string,int> divide(string dividendStr, string divisorStr) {...} // 返回 商 和 余数 的 pair 对象 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值