#define _CRT_SECURE_NO_DEPRECATE 1
#include<stdio.h>
#include<string.h>
#define N 200
#define jc_MAX 4000
//输入
void input_digit(char s1[], char s2[])
{
printf("请输入第一个数:");
scanf("%s", s1);
printf("请输入第二个数:");
scanf("%s", s2);
}
//逆置
void resave(char s1[], char s2[], int a[], int b[], int len_a, int len_b)
{
int i = 0;
for ( i = len_a - 1; i >= 0; i--)
{
a[i] = s1[len_a - i - 1] - '0';
}
for ( i = len_b - 1; i >= 0; i--)
{
b[i] = s2[len_b - i - 1] - '0';
}
}
int max_len(int len_a, int len_b)
{
return (len_a >= len_b) ? len_a : len_b;
}
//加法
void add(int len_a, int len_b, int c[], int a[], int b[])
{
int i = 0;
for ( i = 0; i < max_len(len_a, len_b); i++)
{
c[i] += a[i] + b[i];
c[i + 1] = c[i] / 10;
c[i] %= 10;
}
printf("和是:");
for ( i = max_len(len_a, len_b); i >= 0; i--)
{
if (i == max_len(len_a, len_b) && c[i] == 0)
continue;
printf("%d", c[i]);
}
}
//计算加法过程
void calc_add(char s1[], char s2[], int c[], int a[], int b[])
{
input_digit(s1, s2);
int len_a = strlen(s1);
int len_b = strlen(s2);
resave(s1, s2, a, b, len_a, len_b);
add(len_a, len_b, c, a, b);
}
//减法
//比较长度相等时的大小
int compare(const int a[], const int b[], int len_a)
{
do
{
if (a[len_a - 1] > b[len_a - 1])
{
return 1;
}
else if (a[len_a - 1] < b[len_a - 1])
{
return 0;
}
else
{
len_a--;
}
} while (len_a != 0);
return -1;
}
//比较长度不等时的大小
int heavy_one(int a[], int len_a, int b[], int len_b)
{
if (len_a > len_b)
{
return 1;
}
else if (len_a < len_b)
{
return 0;
}
else
{
return compare(a, b, len_a);
}
}
void sub(int len_a, int len_b, int c[], int a[], int b[])
{
int i;
if (heavy_one(a, len_a, b, len_b) == 1)
{
for ( i = 0; i < max_len(len_a, len_b); i++)
{
if (a[i] < b[i])
{
a[i] += 10;
a[i + 1] -= 1;
}
c[i] = a[i] - b[i];
}
printf("差是:");
}
else
{
for ( i = 0; i < max_len(len_a, len_b); i++)
{
if (b[i] < a[i])
{
b[i] += 10;
b[i + 1] -= 1;
}
c[i] = b[i] - a[i];
}
printf("差是:-");
}
for ( i = max_len(len_a, len_b); i >= 0; i--)
{
if (i == max_len(len_a, len_b) && c[i] == 0)
continue;
printf("%d", c[i]);
}//倒着输出
}
void calc_sub(char s1[], char s2[], int c[], int a[], int b[])
{
input_digit(s1, s2);
int len_a = strlen(s1);
int len_b = strlen(s2);
resave(s1, s2, a, b, len_a, len_b);
sub(len_a, len_b, c, a, b);
}
//乘法
void mul(int len_a, int len_b, int c[], int a[], int b[])
{
int i, j;
int len_c = len_a + len_b;
for ( i = 0; i < len_a; i++)
{
for ( j = 0; j < len_b; j++)
{
c[i + j] += a[i] * b[j];
c[i + j + 1] += c[i + j] / 10;
c[i + j] %= 10;
}
}
while (c[len_c - 1] == 0 && len_c > 1)
{
len_c--;
}
printf("两数之积是:");
for ( i = len_c - 1; i >= 0; i--)
{
printf("%d", c[i]);
}
}
void calc_mul(char s1[], char s2[], int c[], int a[], int b[])
{
input_digit(s1, s2);
int len_a = strlen(s1);
int len_b = strlen(s2);
resave(s1, s2, a, b, len_a, len_b);
mul(len_a, len_b, c, a, b);
}
//阶乘
void Print_Factorial(int n)
{
int a[jc_MAX];
int temp, num, digit; //temp:每一位的结果 num:进位 digit:结果的位数
int i, j;
a[0] = 1;
digit = 1; //从第1位开始
if (n >= 0)
{
for ( i = 2; i <= n; i++)
{
num = 0;
for ( j = 0; j < digit; j++)
{
temp = a[j] * i + num;
num = temp / 10;
a[j] = temp % 10;
}
while (num)
{
a[digit] = num % 10;
num /= 10;
digit++;
}
}
printf("%d的阶乘是:", n);
for (i = digit - 1; i >= 0; i--)
{
printf("%d", a[i]);
}
}
else printf("Invalid input");
}
//除法
int compare_Div(int a[], int b[]) {
//索引为0的数据为数组长度
if (a[0] > b[0]) {
return 1;
}
else if (a[0] < b[0]) {
return -1;
}
int i = 0;
//逐位比较
for ( i = a[0]; i > 0; i--)
{
if (a[i] > b[i])
{
return 1;
}
else if (a[i] < b[i]) {
return -1;
}
}
return 0;
}
void numcpy(int a[], int b[], int dest) {
//将数组右移,使两个数组右端对齐
int i = 1;
for ( i = 1; i <= a[0]; i++)
{
b[i + dest - 1] = a[i];
}
b[0] = a[0] + dest - 1;
}
void Div_re(int a[], int b[], char s1[], char s2[], int len_a, int len_b)
{
int i = 0;
for ( i = 0; i < len_a; i++)
{
a[len_a - i] = s1[i] - '0';
}
for ( i = 0; i < len_b; i++)
{
b[len_b - i] = s2[i] - '0';
}
}
void Div_su(int a[], int b[], int c[], char s1[], int tmp[])
{
int j = 1;
if (0 == compare_Div(a, b))
{
//两数相等
printf("1\n0\n");
}
else if (-1 == compare_Div(a, b))
{
printf("商是:0\n");
printf("余数是:%s\n", s1);
}
else {
c[0] = a[0] - b[0] + 1;
for (int i = c[0]; i > 0; i--) {
memset(tmp, 0, sizeof(tmp));
//高位对齐
numcpy(b, tmp, i);
//
while (compare_Div(a, tmp) >= 0)
{
c[i]++;
//减法
for ( j = 1; j <= a[0]; j++)
{
if (a[j] < tmp[j])
{
a[j + 1]--;
a[j] += 10;
}
a[j] -= tmp[j];
}
int k = a[0];
while (a[k] == 0)
{
k--;
}
a[0] = k;
}
}
//控制最高位的0
while (c[0] > 0 && c[c[0]] == 0)
{
c[0]--;
}
}
//逆序打印输出商和余数
printf("商是:");
for (int i = c[0]; i > 0; i--)
{
printf("%d", c[i]);
}
printf("\n余数是:");
if (0 == a[0])
{
printf("0\n");
}
else
{
for (int i = a[0]; i > 0; i--)
{
printf("%d", a[i]);
}
printf("\n");
}
}
void calc_Div(char s1[], char s2[], int tmp[], int a[], int b[], int c[])
{
int len_a = strlen(s1);
int len_b = strlen(s2);
a[0] = len_a;
b[0] = len_b;
Div_re(a, b, s1, s2, len_a, len_b);
Div_su(a, b, c, s1, tmp);
}
//测试
void stratAdd()
{
char s1[N], s2[N];
int a[N] = { 0 }, b[N] = { 0 }, c[N] = { 0 };
calc_add(s1, s2, a, b, c);
}
void stratSub()
{
char s1[N], s2[N];
int a[N] = { 0 }, b[N] = { 0 }, c[N] = { 0 };
calc_sub(s1, s2, a, b, c);
}
void stratMul()
{
char s1[N], s2[N];
int a[N] = { 0 }, b[N] = { 0 }, c[N] = { 0 };
calc_mul(s1, s2, a, b, c);
}
void stratDiv()
{
char s1[N] = { 0 };//存储字符串
char s2[N] = { 0 };//存储字符串
int tmp[N] = { 0 };//交换用字符串
int a[N] = { 0 };//存储加数A
int b[N] = { 0 };//存储加数B
int c[N] = { 0 };
input_digit(s1, s2);
calc_Div(s1, s2, tmp, a, b, c);
}
void Factorial()
{
int n;
printf("请输入:");
scanf("%d", &n);
Print_Factorial(n);
}
int display()
{
int n;
printf("\n------------------------------------------------\n");
printf("------------------------------------------------");
printf("\n输入1=>加法器\t输入2=>减法\n输入3=>乘法\t输入4=>除法\n\t输入5=>阶乘\n\t输入0=>退出程序\n");
printf("------------------------------------------------");
printf("\n------------------------------------------------\n");
scanf("%d", &n);
return n;
}
void again();
void menu()//定义菜单函数界面
{
int result;
result = display();
switch (result)
{
case 1:
printf("\n高精度加法器:\n");
stratAdd();
again();
break;
case 2:
printf("\n高精度减法器:\n");
stratSub();
again();
break;
case 3:
printf("\n高精度乘法器:\n");
stratMul();
again();
break;
case 4:
printf("\n高精度除法器:\n");
stratDiv();
again();
break;
case 5:
printf("\n高精度求阶乘:\n");
Factorial();
again();
break;
case 0:
printf("退出程序。");
break;
default:
printf("输入格式错误");
again();
break;
}
}
void again()
{
int choice = 0;
printf("\n\n输入“1”继续进行计算;输入任意值退出程序\n请选择:");
scanf("%d", &choice);
if (choice == 1)
{
menu();
}
else
{
printf("退出程序。");
}
}
int main()
{
menu();
return 0;
}
高精度加法与高精度减法同理
就是我们小学的列竖式计算(注意逆置):
同理,高精度乘法:
高精度除以高精度,通过高精度减法的次数来得出商
阶乘: