大数计算器(加减乘除)

#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;
}

高精度加法与高精度减法同理

就是我们小学的列竖式计算(注意逆置):

         

同理,高精度乘法:

高精度除以高精度,通过高精度减法的次数来得出商

阶乘:

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值