题目:大整数计算
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <conio.h>
#define MAX 51 //题目假设大整数最高为50位,所以取长度为MAX(51)的字符数组
void format(int *a) //升位: 低位除10剩余数,高位加商;比如十位的13,变成百位加1和十位剩3
{
int p;
for(p = 1; p < a[0] || a[p] >= 10; p++)
{
if (p >= a[0])
a[p+1] = 0;
a[p+1] += (a[p] / 10); //高位加上除10运算的商
a[p] = a[p] % 10; //低位等于除10运算的余数
}
if (p >= a[0])
a[0] = p;
}
void add(int *a,int *b,int *c)
{
int len,i;
if (a[0] < b[0])
len=a[0];
else
len=b[0];
for(i = 1; i <= len; i++)
{
c[i] = a[i] + b[i];
}
if (len < a[0])
{
for( ; i <= a[0]; i++)
{
c[i] = a[i];
}
c[0] = a[0];
}
else
{
for( ; i <= b[0]; i++)
{
c[i] = b[i];
}
c[0] = b[0];
}
format(c);
}
void commaltiply (int *a, int x, int *b)
{
int i;
for(i = 1; i <= a[0]; i++)
{
b[i] = a[i] * x;
}
b[0] = a[0];
format(b);
}
void matiply(int *a,int *b,int *c)
{
int i,temp[MAX],j;
commaltiply(a, b[1], c);
for(i = 2; i <= b[0]; i++)
{
if(b[i] == 0)
{
c[0]++;
for (j = c[0]; j > 1; j--)
c[1] = 0;
}
else
{
commaltiply(a, b[i], temp);
for(j = 1; j < i; j++)
commaltiply(temp, 10, temp);
add(c, temp, c);
}
}
}
void format1(int *a) //降位: 高位减1 补到 低位成10;比如百位的1相当于十位的10
{
int i;
for(i = 1; i <= a[0]; i++)
if(a[i] < 0)
{
a[i] += 10;
a[i+1] -= 1;
}
}
void sub_1(int *a,int *b,int *c) //默认形参a比b长的减法运算
{
int i;
for(i = 1; i <= b[0]; i++)
c[i] = a[i] - b[i];
if(a[0] != b[0])
{
//初始时 i = b[0],从b[0]开始+1,最终加到a[0]
for ( ; i <= a[0]; i++)
c[i] = a[i];
}
c[0] = a[0];
format1(c);
i = c[0]; //先让i暂存运算结果的位数(长度)
while(1)
{
if(c[i] == 0) //从高位开始检查,如果高位数字为0,则 位数-1
i--;
else //当检查到某较高位数不为0,则退出while循环
break;
}
c[0] = i; //c[0] 存储检查后的位数
}
void sub(int *a, int *b, int *c) //减法
{
int i, flag = 0; //flag用来标记 两个大整数是否相等的
for(i = 1; i <= a[0]; i++) //a[0] 是 大整数的长度
if(a[i] != b[i]) //两个大整数只要有一位数字不相等,则flag = 1
{
flag = 1;
break;
}
if(flag == 0) //如果两个大整数完全相等,则flag不变还是0 则计算结果为0
{
c[0] = 0;
return;
}
flag = 0; //此时flag用来标记 a和b运算减法运算的情况
if(a[0] == b[0]) //如果两个大整数的长度相同
{
for(i = a[0]; i > 0; i--) //从最高位开始比较
{
if(a[i] > b[i]) //如果a的最高位数字比b的大
{
sub_1(a,b,c); //正常执行减法运算
break;
}
if(a[i] < b[i]) //如果a的最高位数字比b的小,b减a,flag=1
{
flag = 1;
sub_1(b,a,c);
break;
}
}
}
if(a[0] > b[0]) //如果a,b的长度不等,且a比b长,直接计算
{
sub_1(a,b,c);
}
else if (a[0] < b[0]) //如果a,b的长度不等,且a比b短,执行b减a
{
flag = 1;
sub_1(b,a,c);
}
if (flag) //执行b减a运算的时候结果应该取相反数
c[0] = -c[0];
else
c[0] = c[0];
}
void read_in(int *a) //读入长整数
{
int len, i;
int flag = 0; // flag用来标记负数的存在,正数记0,负数记1
int flag_error = 0;
char s[MAX];
//如果读入的是负长整数,则字符数组的第一个位置要存储负号
//而且长整数的最大位数为50位,因此需要长度为51的字符数组
//正长整数则不用担心这个问题
while(1)
{
scanf("%s",s);
len = strlen(s);
if (s[0] == '-') flag = 1; //标记负数
for(i = len-flag; i >= 1; i--) //倒序存储
{
if ((s[len-i]-'0') < 0||(s[len-i]-'0') > 9)
{
printf("\t\t\t 第%d位输入错误,按任意键重新输入!",len-i+1);
getch();
flag_error++;
break;
//某位错误,错误标记记1,不再检查其他位数,跳出for循环,检查flag_error
}
else
a[i] = s[len-i] - '0';
/* 如果第i位没错,把该位的数字字符转换成数字存入a[]数组中
* s[len-i]-'0'是利用 数字字符的ASCII码和数字本身数值大小的关系
* 来实现 字符转换成数字 的功能 */
} // end for
if(flag_error)
continue;
//continue:不执行后面的语句,重新开始一次while循环
if (flag)
a[0] = -(len-1);
else
a[0] = len;
break;
} // end while
}
void print(int *a)
{
int i;
if (a[0] < 0)
{
printf("-");
}
if (a[0] == 0)
{
printf("0");
return;
}
for(i = abs(a[0]); i >= 1; i--) //倒序输出
printf("%d",a[i]);
printf("\n");
}
char menu() //功能菜单
{
char ans; // answer的简写,用于存储用户输入的回答
while(1)
{
printf("\n\n\n");
printf("\t\t\t\t————————————————\n");
printf("\t\t\t\t| > 长整数计算器 < |\n");
printf("\t\t\t\t| |\n");
printf("\t\t\t\t| 1.大整数的加法 |\n");
printf("\t\t\t\t| 2.大整数的减法 |\n");
printf("\t\t\t\t| 3.大整数的乘法 |\n");
printf("\t\t\t\t| 4.退出 |\n");
printf("\t\t\t\t| |\n");
printf("\t\t\t\t————————————————\n");
printf("\n\n\n\t\t\t 请选择功能(1-4): ");
ans = getchar();
if(ans == '1'||ans == '2'||ans == '3'||ans == '4')
break;
else
{
getch();
printf("\n\t\t\t 输入错误!按任意键重新输入!!!!");
getch();
system("cls");
}
}
return ans;
}
int main()
{
int a[MAX],b[MAX],c[MAX];
// a存储第一个长整数,b存储第二个,c存储运算结果
char ans; // answer的简写,用于存储用户输入的回答
while(1)
{
ans = menu();
if(ans == '4') return 0; //先判断是否要退出
printf("\n\t\t\t 请输入大整数A: ");
read_in(a);
printf("\n\t\t\t 请输入大整数B: ");
read_in(b);
if (ans == '1')
{
if (a[0] < 0 && b[0] < 0)
{
a[0] = -a[0];
b[0] = -b[0];
add(a,b,c);
c[0] = -c[0];
a[0] = -a[0];
b[0] = -b[0];
}
if (a[0] > 0 && b[0] < 0)
{
b[0] = -b[0];
sub(a,b,c);
b[0] = -b[0];
}
else if (a[0] > 0 && b[0] > 0)
{
add(a,b,c);
}
else if (a[0] < 0 && b[0] > 0)
{
a[0] = -a[0];
sub(b,a,c);
a[0] = -a[0];
}
printf("\n\t\t\t A = ");
print(a);
printf("\n\t\t\t B = ");
print(b);
printf("\n\t\t\t C = A+B = ");
print(c);
} // end if(rn=='1')
else if (ans == '2')
{
if (a[0] < 0 && b[0] < 0)
{
a[0] = -a[0];
b[0] = -b[0];
sub(b,a,c);
a[0] = -a[0];
b[0] = -b[0];
}
if (a[0] < 0 && b[0] > 0)
{
a[0] = -a[0];
add(a,b,c);
a[0] = -a[0];
c[0] = -c[0];
}
if (a[0] > 0 && b[0] < 0)
{
b[0] = -b[0];
add(a,b,c);
b[0] = -b[0];
}
if (a[0] > 0 && b[0] > 0)
sub(a,b,c);
printf("\n\t\t\t A = ");
print(a);
printf("\n\t\t\t B = ");
print(b);
printf("\n\t\t\t C = A-B = ");
print(c);
} // end if(rn=='2')
else if (ans == '3')
{
if (a[0] < 0 && b[0] > 0)
{
a[0] = -a[0];
matiply(a,b,c);
a[0] = -a[0];
c[0] = -c[0];
}
else if (a[0] > 0 && b[0] < 0)
{
b[0] = -b[0];
matiply(a,b,c);
b[0] = -b[0];
c[0] = -c[0];
}
else if (a[0] < 0 && b[0] < 0)
{
a[0] = -a[0];
b[0] = -b[0];
matiply(a,b,c);
a[0] = -a[0];
b[0] = -b[0];
}
else
matiply(a,b,c);
printf("\n\t\t\t A = ");
print(a);
printf("\n\t\t\t B = ");
print(b);
printf("\n\t\t\t C = A*B = ");
print(c);
} // end if(rn=='3')
while(1)
{
printf("\n\t\t\t 是否继续计算?(y/n): ");
getchar();
ans = getchar();
if(ans == 'y' || ans == 'Y')
{
system("cls");
getchar();
break;
}
else
return 0;
} // end inside while
} // end outside while
} // end main
代码分析:
运行结果: