⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 大整数加减运算源程序.c

📁 多数程序设计语言处理整数的能力时有限的
💻 C
字号:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define LEN sizeof(struct lnode)
#define NULL 0
struct lnode      /*定义结构体类型*/
{
	int data;    /*数据域*/
	struct lnode *next;     /*指针域*/   
};
struct lnode *creat(int *len)   /*创建链表存放大整数,len用于求所输入的大整数的位数*/
{
	struct lnode *h,*p,*q;
	char x;
	q=h=(struct lnode *)malloc(LEN);  /*生成头结点*/
	x=getchar();     /*输入大整数的符号,并存放在头结点中*/
	h->data=x;
	while((x=getchar())!='\n')   /*输入大整数并存放在链表中,以回车键结束*/
	{
		(*len)++;    /*统计大整数的位数*/
	    p=(struct lnode *)malloc(LEN);    /*开辟新的结点存放数据*/
	    p->data=x-'0';     /*把输入的数存放在新开辟的结点中*/
	    q->next=p;
	    q=p;
	}
	q->next=NULL;
	return(h);
}

void print(struct lnode *h)    /*打印大整数以及计算结果*/
{
	struct lnode *p,*t;   /*定义指针变量*/
    p=h;        /*把指针变量指向头结点*/
	printf("%c",p->data);   /*打印大整数的符号*/
	p=p->next;
	if(p->next==NULL&&p->data==0)    /*如果计算结果为0,则输出0*/
		printf("\n\t%d.\n",p->data);
	else
	{
		while(p&&p->data==0)    /*去掉开头的0,保证在开头第一个结点中的数是以实际输出,不带补充的0*/
		{
			t=p;
			p=p->next;
			free(t);
		}
		while(p!=NULL)    
		{
			printf("%d",p->data);
			p=p->next;
		}
	printf("\n");
	}
}

struct lnode *nizhuan(struct lnode *h)  /*逆转大整数*/
{
	struct lnode *p,*q;

	if(h->next&&h->next->next)    /*当大整数的位数有三位以上时,进行逆转*/
	{
		p=h->next;      /*指针p指向大整数的第一位*/
		q=p->next;      /*指针q指向大整数的第二位*/
		p->next=NULL;   /*在大整数的第一位与第二位之间断开,原来的链表变为两个*/

	while(q)    /*每次将指针q指向第二个链表的第一个结点,插入到头结点的下一位*/
	{
        p=q;
		q=q->next;
		p->next=h->next;
		h->next=p;
	}
}
	return(h);
}

struct lnode *add(struct lnode *h1,struct lnode *h2)    /*大整数加法运算*/
{
	int f=0;    /*进位标志,初始化为0*/
	struct lnode *h3;
    struct lnode *p,*q,*s;
	h1=nizhuan(h1);   /*由于大整数运算由最低开始进行,所以必须先把存放在链表中的大整数逆转*/
	h2=nizhuan(h2);
	p=h1;      /*把定义的两个指针变量p,q分别指向两个链表的头结点*/
	q=h2;
    s=h3=(struct lnode *)malloc(LEN);   /*创建第三个链表存放计算结果*/
    s->data=p->data;    /*计算结果的符号为其中一个大整数的符号*/
    p=p->next;
    q=q->next;
    while(p!=NULL&&q!=NULL)   /*当两个大整数的位数相同时*/
	{
		s->next=(struct lnode *)malloc(LEN);
		s=s->next;
	    s->data=p->data+q->data+f;  
		if(s->data>=10)    /*当结果大于或等于10时进位标志设为1,并把计算结果减去10*/
		{
			s->data=s->data-10;
			f=1;
		}
		else
			f=0;
		p=p->next;
		q=q->next;

	}
	while(p!=NULL)    /*当第一个大整数的位数大于第二个大整数时,将第一个大整数的非空结点copy到计算结果*/
	{
        s->next=(struct lnode *)malloc(LEN);
		s=s->next;
		s->data=p->data+f;
		if(s->data>=10)      /*当结果大于或等于10时进位标志设为1,并把计算结果减去10*/
		{
			s->data=s->data-10;
			f=1;
		}
		else
			f=0;
		p=p->next;
	}
	while(q!=NULL)     /*当第二个大整数的位数大于第一个大整数时,将第二个大整数的非空结点加上f后copy到计算结果*/
	{
        s->next=(struct lnode *)malloc(LEN);
		s=s->next;
		s->data=q->data+f;
		if(s->data>=10)     /*当结果大于或等于10时进位标志设为1,并把计算结果减去10*/
		{
			s->data=s->data-10;
			f=1;
		}
		else
			f=0;
		q=q->next;
	}
	if(p==NULL&&q==NULL&&f==1)   /*当最高位计算完毕后出现进位的时候,开辟一个新的结点存储进位*/
	{
		s->next=(struct lnode *)malloc(LEN);    
		s=s->next;
		s->data=f;
	}
	s->next=NULL;
	return(h3);    /*返回计算结果的头指针*/
}

struct lnode *sub(struct lnode *h1,struct lnode *h2)  /*位数不同的大整数减法运算*/
{
	struct lnode *h3;
	struct lnode *p,*q,*s;
	int f=0;    /*初始化借位标志*/
	h1=nizhuan(h1);   /*由于大整数运算由最低开始进行,所以必须先把存放在链表中的大整数逆转*/
	h2=nizhuan(h2);
    p=h1;    /*把定义的指针变量p,q分别指向两个存放大整数的链表的头结点*/
	q=h2;
	s=h3=(struct lnode *)malloc(LEN);   /*创建第三个链表存放计算结果*/
    s->data=p->data;    /*计算结果的符号为位数多的大整数的符号*/
    p=p->next;
    q=q->next;
    while(q!=NULL)  
	{
		s->next=(struct lnode *)malloc(LEN);
		s=s->next;
	    if((p->data)>=(q->data))
		{
			s->data=p->data-q->data+f;
			f=0;
		}
		if((p->data)<(q->data))   /*当需要借位时把借位标志设为-1*/
		{

			s->data=(p->data)+10-(q->data)+f;
			f=-1;
		}
		if(s->data<0)   /*当s的值小于0时,把所得的值加10,并把借位标志设为-1*/
		{
			s->data=s->data+10;
			f=-1;
		}
		p=p->next;
		q=q->next;
	}
	while(p!=NULL)
	{
		s->next=(struct lnode *)malloc(LEN);
		s=s->next;
		if(p->data==0)    /*当需要借位时把借位标志设为-1*/
		{
			s->data=p->data+10+f;
		    f=-1;
		}
		else
		{
			s->data=p->data+f;   /*否则把位数多的大整数的非空结点加上f后copy到计算结果中*/
		f=0;
		}
		p=p->next;
	}
	s->next=NULL;
	return(h3);    /*返回计算结果的头指针*/
}

struct lnode *sub1(struct lnode *h1,struct lnode *h2)  /*位数相同的大整数减法运算*/
{
	struct lnode *h3;
	struct lnode *p,*q,*s;
	int flag=0,f=0;   /*若第一个数大于第二个数,flag则设为1,f为借位标志*/
	p=h1->next;
	q=h2->next;
	s=h3=(struct lnode *)malloc(LEN);
	while(p!=NULL&&q!=NULL)   /*比较两个大整数的大小*/
	{
		if(p->data>q->data)   
			{
				h3->data=h1->data; /*若第一个数大于第二个数,计算结果的符号为第一个数的符号*/
				flag=1;     
			break;
			}
			
			else if(p->data<q->data)
			{
				h3->data=h2->data;  /*若第一个数小于第二个数,计算结果的符号为第二个数的符号*/
			break;
			}
        p=p->next;
		q=q->next;
	}
	h1=nizhuan(h1);  /*由于大整数运算由最低开始进行,所以必须先把存放在链表中的大整数逆转*/
	h2=nizhuan(h2);
	p=h1->next;
	q=h2->next;
	while(p!=NULL&&q!=NULL)  
	{
		if(flag==1)   /*当第一个数大于第二个数,用第一个数的对应位减去第二个数的对应位*/
		{
			s->next=(struct lnode *)malloc(LEN);
		    s=s->next;
			if((p->data)>=(q->data))
			{
				s->data=p->data-q->data+f;
				f=0;
			}
			if((p->data)<(q->data))
			{
				s->data=(p->data)+10-(q->data)+f;   /*当需要借位时把借位标志设为-1*/
				f=-1;
			}
		}
		else     /*当第二个数大于第一个数,用第二个数的对应位减去第一个数的对应位*/
		{
			s->next=(struct lnode *)malloc(LEN);
		    s=s->next;
			if((q->data)>=(p->data))
			{
				s->data=q->data-p->data+f;
				f=0;
			}
			if((q->data)<(p->data))
			{
				s->data=(q->data)+10-(p->data)+f;   /*当需要借位时把借位标志设为-1*/
				f=-1;
			}
		}
			p=p->next;
			q=q->next;
	}
	s->next=NULL;
	return(h3);    /*返回计算结果的头指针*/
}

menu()    /*显示该程序的相关功能*/
{printf("\t\t                  ***欢迎使用!***\n");
 printf("\t\t **************************************************\n");
 printf("\t\t|                  1.输入并输出数据                |\n");
 printf("\t\t|                  2.加法运算                      |\n");
 printf("\t\t|                  3.减法运算                      |\n");
 printf("\t\t|                  4.退出系统                      |\n");
 printf("\t\t **************************************************\n");
}
main()    /*主函数*/
{
	struct lnode *h1,*h2,*h3;  
	char ch;
	char c;
	int i;
	int *len1,*len2;   
	int x=0,y=0;
	len1=&x;   /*初始化符号*/
	len2=&y;
	menu();
  start:printf("\ninput your opt:\n");
	scanf("%d",&i);
	switch(i)
	{
	case 1:
		    if((c=getchar())=='\n')   /*产生两个大整数*/
			{	
				printf("请以输入一个数:\n");	 
				h1=creat(len1);
				printf("请以输入另一个数:\n");
				h2=creat(len2);
				printf("一个数是:");
			    print(h1);
				printf("另一个数是:");
			    print(h2);
			    goto start;
			}
	case 2:
		{
			if(h1->data==h2->data)   /*如果两个大整数的符号相同,则调用加法函数*/
			{
				h3=add(h1,h2); 
				printf("进行加法运算所得结果是:");
				h3=nizhuan(h3);   /*逆转计算结果,使计算结果以正常顺序输出*/
				print(h3);   /*打印结果*/
				h1=nizhuan(h1);  /*把两个大整数逆转为原来顺序,以便进行另一种运算*/
				h2=nizhuan(h2);
			}
			if(h1->data!=h2->data)   /*若两个大整数的符号不同时,相加转化为相减*/
			{
                if((*len1)>(*len2))
					h3=sub(h1,h2);
			    if((*len1)<(*len2))
					h3=sub(h2,h1);
				if((*len1)==(*len2))
					h3=sub1(h1,h2);
			    printf("进行加法运算所得结果是:");
			    h3=nizhuan(h3);	 /*逆转计算结果,使计算结果以正常顺序输出*/
				print(h3);    /*打印结果*/
				h1=nizhuan(h1);  /*把两个大整数逆转为原来顺序,以便进行另一种运算*/
				h2=nizhuan(h2);
			}
			goto start;
		}
	case 3:
		{
			if(h1->data==43&&h2->data==43)   /*当两个大整数为负数时减法运算*/  
			{
				h2->data=45;
			    if((*len1)>(*len2))
					h3=sub(h1,h2);
			    if((*len1)<(*len2))
					h3=sub(h2,h1);
				if((*len1)==(*len2))
					h3=sub1(h1,h2);
			    printf("进行减法运算所得结果是:");
			    h3=nizhuan(h3);	  /*逆转计算结果,使计算结果以正常顺序输出*/
				print(h3);   /*打印结果*/
		        h2->data=43;
				h1=nizhuan(h1);  /*把两个大整数逆转为原来顺序,以便进行另一种运算*/
				h2=nizhuan(h2);
			}
			if(h1->data==45&&h2->data==45)   /*当两个大整数为正数时的减法运算*/
			{
				h2->data=43;
			    if((*len1)>(*len2))
					h3=sub(h1,h2);
			    if((*len1)<(*len2))
					h3=sub(h2,h1);
				if((*len1)==(*len2))
					h3=sub1(h1,h2);
			    printf("进行减法运算所得结果是:");
			    h3=nizhuan(h3);	  /*逆转计算结果,使计算结果以正常顺序输出*/
				print(h3);    /*打印结果*/
			    h2->data=45;
				h1=nizhuan(h1);   /*把两个大整数逆转为原来顺序,以便进行另一种运算*/
				h2=nizhuan(h2);
			}
			if(h1->data!=h2->data)   /*两个符号不同的大整数相减,可看成是两个符号相同的大整数相加*/
			{
				h3=add(h1,h2); 
				printf("进行减法运算所得结果是:");
				h3=nizhuan(h3);   /*逆转计算结果,使计算结果以正常顺序输出*/
				print(h3);
				h1=nizhuan(h1);  /*把两个大整数逆转为原来顺序,以便进行另一种运算*/
				h2=nizhuan(h2);
			}
		goto start;
		}
	case 4:
		{
			printf("是否退出系统?(y/n)\n");   /*判断是否推出系统*/
		        getchar();
		        ch=getchar();
		        getchar();
		    if(ch=='y'||ch=='Y')
		       exit(0); 
		    else 
			   goto start;
		}
		 default:printf("Sorry!\nError!\nPlease input again.\n");
			 goto start;
	}
}




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -