📄 big_int.c
字号:
/********************************************/
/* 程序名称:大整数加减法 */
/*语言:C 编译环境:VC++6.0 */
/*完成人员:罗成行 */
/* 班级:03计算机(1)班 学号:2003374119 */
/* 完成时间:05年4月4日 */
/********************************************/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "help.h"
#define New_node (Big_node)malloc(sizeof(Big_int))
#define MaxSize 500
#define Max 9999 //一个节点存放的最大数据
#define False 0
#define True 1
typedef struct Big_int Big_int,*Big_node;
struct Big_int{ //定义节点的类型
int data; //节点存放的数据,从0~9999
int sign; //节点数据的正负号
Big_node pre; //指向下一个节点;
Big_node next; //指向前一个节点
};
/*---------------------------------------------*/
void Menu()
//菜单函数
{
printf("\n\t\t=============Big integral==============\n");
printf("\n\t\t Please choose a function:");
printf("\n\t\t 1.Adjust to use the big integral addition.");
printf("\n\t\t 2.Adjust to use the big integral subtraction.");
printf("\n\t\t 3.Help.");
printf("\n\t\t 0.Exit.\n\n");
printf("\t\t===============================\n");
printf("\nPlease input number:");
}//Menu();
void main(void){
int Input(char *); //从键盘输入一个大整数
void Due(char *,Big_node); //把大整数处理成用双链表的方式存储
Big_node Add(Big_node,Big_node);//两个为正的大整数加法运算
Big_node Sub(Big_node,Big_node);//两个为正的大整数减法运算
int Judge(Big_node,Big_node); //判断两个大整数的正负号
int Compare(Big_node,Big_node);//比较两个大整数的绝对值
//Big_node Multi();
//Big_node Div();
void Print(Big_node); //输出链表所存放的大整数
char a1[MaxSize],a2[MaxSize];
int i,j,com;
char a[100];
char re_choose[]={"\nThe choice is invalid, please re- choose...\n"};
Big_node h1,h2,h;
h1=New_node;
h2=New_node;
while(1)
{
Menu();
for(j=0;j<100;j++)
{
scanf("%c",&a[j]);
if(a[j]=='\n') break;
} /*功能选择*/
if(a[1]!='\n'){
printf("\n%s",re_choose);
system("pause");
system("cls");
continue;
}
else{
if(a[0]=='0') break;
switch(a[0])
{
case '1' ://进行加法运算
do{
printf("Please import the summand:");
}while(!Input(a1));
Due(a1,h1);
do{
printf("Please import the addend:");
}while(!Input(a2)) ;
Due(a2,h2);
i=Judge(h1,h2);
switch(i){
case 0 ://两个大整数都是正号的
h=Add(h1,h2);
break;
case 3 ://两个都是负号的
h=Add(h1,h2);
h->sign=1;
break;
case 1 ://第一个是正号,第二个是负号
com=Compare(h1,h2);
if(!com){
h=Sub(h1,h2);
h->sign=0;
}
else{
h=Sub(h2,h1);
h->sign=1;
}
break;
case 2 ://第一个是负号,第二个是正号
com=Compare(h1,h2);
if(!com){
h=Sub(h1,h2);
h->sign=1;
}
else{
h=Sub(h2,h1);
h->sign=0;
}
break;
}//End switch
printf("\n(");
Print(h1);
printf(")+(");
Print(h2);
printf(")=");
Print(h);
printf("\n\n\n");
system("pause");
system("cls");
break;
case '2' ://大整数减法运算
do{
printf("Please import the minuend:");
}while(!Input(a1)) ;
Due(a1,h1);
do{
printf("Please import the subtrahend:");
}while(!Input(a2)) ;
Due(a2,h2);
i=Judge(h1,h2);
switch(i){
case 0 ://两个都是正号的
com=Compare(h1,h2);
if(!com){
h=Sub(h1,h2);
h->sign=0;
}
else{
h=Sub(h2,h1);
h->sign=1;
}
break;
case 3 ://两个都是负号的
com=Compare(h1,h2);
if(!com){
h=Sub(h1,h2);
h->sign=1;
}
else{
h=Sub(h2,h1);
h->sign=0;
}
break;
case 1 ://第一个是正号,第二个是负号
h=Add(h1,h2);
h->sign=0;
break;
case 2 ://第一个是负号,第二个是正号
h=Add(h1,h2);
h->sign=1;
break;
}//End switch
printf("\n(");
Print(h1);
printf(")-(");
Print(h2);
printf(")=");
Print(h);
printf("\n\n\n");
system("pause");
system("cls");
break;
case '3' ://说明文件
system("cls");
Help();
printf("\n\n\n");
system("pause");
system("cls");
break;
default :
printf("%s",re_choose);
system("pause");
system("cls");
}//end switch
}//end else
}//end while
}
int Judge(Big_node h1,Big_node h2){
//判断两个大整数的正负号,两个为正返回0,两个为负返回3,
//第一个为正,第二个为负返回1,第一个为负,第二个为正返回2.
if(h1->sign==0 && h2->sign==0)
return 0;
else if(h1->sign==0 && h2->sign==1)
return 1;
else if(h1->sign==1 && h2->sign==0)
return 2;
else if(h1->sign==1 && h2->sign==1)
return 3;
else return 4;
}
int Compare(Big_node h1,Big_node h2){
//比较两个大整数的绝对值
//若h1>=h2,则返回0;否则返回1.
Big_node p1,p2;
p1=h1;p2=h2;
while(p1->next!=h1 && p2->next!=h2){
p1=p1->next;
p2=p2->next;
}
if(p1->next!=h1)
return 0; //h1大
else if(p2->next!=h2)
return 1;
else {
p1=h1;p2=h2;
while(p1->pre!=h1){
p1=p1->pre;
p2=p2->pre;
if(p1->data > p2->data)
return 0;
else if(p1->data < p2->data)
return 1;
}
return 0;
}
}
/*---------------------------------------------*/
int Input(char *a){
//从键盘输入一个大整数
char re_input[]={"Please Re-input!"};
int flag=0,len,i;
//printf("Input Big int :");
scanf("%s",a);
len=strlen(a);
if(a[0]=='-') flag=1;
if(a[flag]=='0' && a[flag+1]>='0' && a[flag+1]<='9'){
printf("\nYou can notinput first number is 0.\n\n%s\n\n",re_input);
return False;
}
for(i=len-1;i>=flag;i--){
if( a[i]<'0' || a[i]>'9' ){//输入的不是数字,输出错误信息并返回
printf("\nYou input the %dth number is wrong.%s\n\n",i+1,re_input);
return False;
}
}
return True;
}
void Due(char *a,Big_node h){
//把大整数处理成用双链表的方式存储.
//若是负数,把链表中sign部分置为1,是正数则置为0;
int b[]={1,10,100,1000};
int len,flag=0,i,round=0,sum=0;
Big_node p,p1;
p=h;
len=strlen(a);
if(a[0]=='-') flag=1;
p->sign=flag;
for(i=len-1;i>=flag;i--){
if(round==4){//当取的长度达到4位就开辟新节点
p1=New_node;
p1->data=sum;
p->next=p1;
p1->pre=p;
p=p1;
p->sign=flag;
sum=0;round=0;
sum+=(int)(a[i]-'0')*b[round++];
}
else{
sum+=(int)(a[i]-'0')*b[round++];
}
}
p1=New_node;
p1->data=sum;
p->next=p1;
p1->pre=p;
p=p1;
p->next=h;
h->pre=p;
}
/*---------------------------------------------*/
Big_node Add(Big_node h1,Big_node h2){
//两个为正的大整数加法运算
Big_node h,p1,p2,p,p3;
int carry=0;
h=p=New_node;
p1=h1;p2=h2;
while(p1->next!=h1 && p2->next!=h2){
//某一个大整数读取完了
p1=p1->next;
p2=p2->next;
p3=New_node;//开辟新节点存放
p->next=p3;
p3->pre=p;
p=p3;
p->data=p1->data + p2->data + carry;
if(p->data>Max){
p->data=p->data - 10000;
carry=1;
}
else
carry=0;
}//End while
if(p1->next==h1){//h2表示的大整数未读取完
while(p2->next!=h2){
p2=p2->next;
p3=New_node;//开辟新节点存放
p->next=p3;
p3->pre=p;
p=p3;
p->data=p2->data + carry;
if(p->data>Max){//超出节点最大的数据范围
p->data=p->data - 10000;
carry=1;
}
else
carry=0;
}//End while
}//End if
else {//h1表示的大整数未读取完
while(p1->next!=h1){
p1=p1->next;
p3=New_node;//开辟新节点存放
p->next=p3;
p3->pre=p;
p=p3;
p->data=p1->data + carry;
if(p->data>Max){//超出节点最大的数据范围
p->data=p->data - 10000;
carry=1;
}
else
carry=0;
}//End while
}//End else
if(carry){//最高位尚有进位,另外开辟新节点
p3=New_node;//开辟新节点存放
p->next=p3;
p3->pre=p;
p=p3;
p->data=carry;
}
p->next=h;
h->pre=p;
return h;
}
/*---------------------------------------------*/
Big_node Sub(Big_node h1,Big_node h2){
//两个为正的大整数减法运算,默认是h1比h2大
Big_node h,p,p1,p2,p3;
int carry=0;
h=p=New_node;
p1=h1;p2=h2;
while(p1->next!=h1 && p2->next!=h2){
//某一个大整数读取完了
p1=p1->next;
p2=p2->next;
p3=New_node;//开辟新节点存放
p->next=p3;
p3->pre=p;
p=p3;
p->data=p1->data - p2->data - carry;
if(p->data<0){
p->data=p->data + 10000;
carry=1;
}
else
carry=0;
}//End while
if(p1->next!=h1){
//h1未读取完
if(carry){//若之前还有借位
p1=p1->next;
p3=New_node;//开辟新节点存放
p->next=p3;
p3->pre=p;
p=p3;
p->data=p1->data-carry;
while(p1->next!=h1){
p1=p1->next;
p3=New_node;
p->next=p3;
p3->pre=p;
p=p3;
p->data=p1->data;
}
}//End if
else {//连接h1未读取的部分
while(p1->next!=h1){
p1=p1->next;
p3=New_node;//开辟新节点存放
p->next=p3;
p3->pre=p;
p=p3;
p->data=p1->data;
}
}//End else
}
p->next=h;
h->pre=p;
return h;
}
/*---------------------------------------------*/
void Print(Big_node h){
//输出链表所存放的大整数
Big_node p=h;
int flag=0;//flag为0就代表该数为0
while(p->pre!=h){
flag+=p->pre->data;
p=p->pre;
}
if(!flag) {//若该数为0,只输出一个0
printf("0");
return;
}
else{
p=h;
if(p->sign==1) printf("-");
if(p->pre->data==0) ;
else
printf("%d",p->pre->data);
p=p->pre;
while(p->pre!=h){
if(p->pre->data==0)
printf("0000");
else{
if(p->pre->data<1000)
//若存放的数据是三位数,在前面添加一个0
printf("0");
else if(p->pre->data<100)
//若存放的数据是两位数,在前面添加两个0
printf("00");
else if(p->pre->data<10)
//若存放的数据是一位数,在前面添加三个0
printf("000");
printf("%d",p->pre->data);//输出节点存放的数据
}
p=p->pre;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -