C语言无符号整数高精度算法试写

大一进了CS专业,偶然听说系里有一个软件设计大赛,于是想报名试试,打算写一个多功能计算器,目前实现了高精度的加减乘(整数)。
思路大概是:
1.通过字符串获得两个操作数。
2.利用循环储存到整型数组中。
3.利用循环做计算。
4.利用循环输出数组。
代码如下:(malloc的时候空间会多几个字节,懒得去精确分配了。不过比a[9999]省不少内存。

#define _CRT_SECURE_NO_WARNINGS


#include <stdio.h>
#include <string.h>
#include <windows.h>

extern void add(int d);//加法函数声明,d=1表示显示没有用但是看起来很爽的过程
extern void sub(int d);//减法函数声明,d=1表示显示没有用但是看起来很爽的过程
extern void mul(int d);//乘法函数声明,d=1表示显示没有用但是看起来很爽的过程


extern void add(int d)
{
    int *a, *b;
    char s1[9999], s2[9999];
    int la, lb, M;
    int i;
    printf("高精度加法开始......\n");
    printf("请输入要计算的第一个数:\n");
    scanf("%s", s1);//输入第一个数
    printf("请输入要计算的第二个数:\n");
    scanf("%s", s2);//输入第二个数
    la = strlen(s1);//取第一个数长度
    lb = strlen(s2);//取第二个数长度
    a = (int*)malloc(sizeof(int)*(la + 2));//分配空间储存加法操作数
    b = (int*)malloc(sizeof(int)*(lb + 2));//分配空间储存加法操作数
    if (d == 1)
    {
        Sleep(500);
        printf("-----空间分配完毕\n");
    }
    for (i = 0; i <= la + 1; i++)//加法操作数置零
        a[i] = 0;

    for (i = 0; i <= lb + 1; i++)//加法操作数置零
        b[i] = 0;

    if (d == 1)
    {
        Sleep(500);
        printf("-----初始操作数置零完毕\n");
    }
    a[0] = la;//存储位数
    b[0] = lb;//存储位数
    /*记录下来位数,本来以为的功能可能会用到,但是觉得要用太麻烦了,就没打算用,也懒得改了。*/
    if (la >= lb)
        M = la;
    else
        M = lb;
    for (i = 1; i <= la; i++)//倒序存储
    {
        a[i] = s1[a[0] - i] - '0';
    }
    for (i = 1; i <= lb; i++)//倒序存储
    {
        b[i] = s2[b[0] - i] - '0';
    }
    if (d == 1)
    {
        Sleep(500);
        printf("-----操作数存储完毕\n");
    }
    if (d == 1)
    {
        Sleep(500);
        printf("-----开始计算\n");
    }
    for (i = 1; i <= M; i++)//竖式加法
    {
        a[i + 1] += (a[i] + b[i]) / 10;//进位
        a[i] = (a[i] + b[i]) % 10;
    }
    if (a[i] > 0)//判断最高位是否进位
        a[0] += 1;

    printf("计算结果为:");
    for (i = a[0]; i >= 1; i--)
        printf("%d", a[i]);

    free(a);
    free(b);
    if (d == 1)
        printf("\n-----内存空间释放完毕");
    system("pause");
}

extern void sub(int d)
{
    int *a, *b;
    char s1[9999], s2[9999];
    int la, lb, M, f;//f=1代表结果为正,反之为负
    int i;
    printf("高精度减法开始......\n");
    printf("请输入要计算的第一个数:\n");
    scanf("%s", s1);//输入第一个数
    printf("请输入要计算的第二个数:\n");
    scanf("%s", s2);//输入第二个数
    if (strcmp(s1, s2) == 0)//如果两个操作数相等
    {
        printf("计算结果为:0");
        goto A;
    }
    la = strlen(s1);//取第一个数长度
    lb = strlen(s2);//取第二个数长度
    if (la >= lb)
        M = la;
    else
        M = lb;
    a = (int*)malloc(sizeof(int)*(M + 2));//分配空间储存减法操作数
    b = (int*)malloc(sizeof(int)*(M + 2));//分配空间储存减法操作数
    if (d == 1)
    {
        Sleep(500);
        printf("-----空间分配完毕\n");
    }
    for (i = 0; i <= la + 1; i++)//减法操作数置零
        a[i] = 0;

    for (i = 0; i <= la + 1; i++)//减法操作数置零
        b[i] = 0;
    if (d == 1)
    {
        Sleep(500);
        printf("-----初始操作数置零完毕\n");
    }

    a[0] = la;//存储位数
    b[0] = lb;//存储位数
    /*记录下来位数,本来以为的功能可能会用到,但是觉得要用太麻烦了,就没打算用,也懒得改了。*/
    for (i = 1; i <= M; i++)//倒序存储
    {
        if (i <= la)
            a[i] = s1[a[0] - i] - '0';
        else
            a[i] = 0;
    }
    for (i = 1; i <= M; i++)//倒序存储
    {
        if (i <= lb)
            b[i] = s2[b[0] - i] - '0';
        else
            b[i] = 0;
    }
    if (d == 1)
    {
        Sleep(500);
        printf("-----操作数存储完毕\n");
    }
    if (d == 1)

    {
        Sleep(500);
        printf("-----开始计算\n");
    }
    if (a[0] > b[0])//依据位数比较大小
        f = 1;
    else
    {
        if (a[0] < b[0])//依据位数比较大小
            f = 0;
        else
        {
            for (i = a[0]; i>0; i--)//从高位开始比较大小
            {
                if (a[i] > b[i])
                    f = 1;
                if (a[i] < b[i])
                    f = -1;
            }
        }
    }
    if (f == 1)//竖式减法
    {
        for (i = 1; i <= M; i++)
        {
            if (a[i] < b[i])//借位
            {
                a[i + 1] -= 1;
                a[i] = 10 - b[i] + a[i];
            }
            else
            {
                a[i] = a[i] - b[i];
            }

        }
        for (i = a[0]; i >= 1; i--)
        {
            if (a[a[0]] == 0 && i == a[0])//如果第一位为0则不输出第一位
                continue;
            printf("%d", a[i]);
        }
        free(a);
        free(b);
    }
    else
    {
        for (i = 1; i <= M; i++)
        {
            if (b[i] < a[i])//借位
            {
                b[i + 1] -= 1;
                b[i] = 10 - a[i] + b[i];
            }
            else
            {
                b[i] = b[i] - a[i];
            }

        }
        printf("计算结果为:");
        printf("结果为负数:\n");
        for (i = b[0]; i >= 1; i--)
        {
            if (b[b[1]] == 0 && i == b[0])//如果第一位为0则不输出第一位
                continue;
            printf("%d", b[i]);
        }
        free(a);
        free(b);
    }
    if (d == 1)
        printf("\n-----内存空间释放完毕");
A://goto标号点
    system("pause");
}

extern void mul(int d)
{
    int *a, *b, *c;
    int i, j, la, lb;
    char s1[9999], s2[9999];
    printf("高精度乘法开始......\n");
    printf("请输入要计算的第一个数:\n");
    scanf("%s", s1);//输入第一个数
    printf("请输入要计算的第二个数:\n");
    scanf("%s", s2);//输入第二个数
    la = strlen(s1);//取第一个数长度
    lb = strlen(s2);//取第二个数长度
    a = (int*)malloc(sizeof(int)*(la + 2));//分配空间储存乘法操作数
    b = (int*)malloc(sizeof(int)*(lb + 2));//分配空间储存乘法操作数
    c = (int*)malloc(sizeof(int)*(la + lb + 2));//分配空间储存乘法计算结果
    if (d == 1)
    {
        Sleep(500);
        printf("-----空间分配完毕\n");
    }
    for (i = 0; i <= la + 1; i++)//乘法操作数置零
        a[i] = 0;

    for (i = 0; i <= lb + 1; i++)//乘法操作数置零
        b[i] = 0;

    if (d == 1)
    {
        Sleep(500);
        printf("-----初始操作数置零完毕\n");
    }

    for (i = 0; i <= la + lb + 1; i++)//乘法计算结果置零
        c[i] = 0;

    for (i = la - 1, j = 0; i >= 0; i--, j++)//倒序存储
        a[j] = s1[i] - '0';

    for (i = lb - 1, j = 0; i >= 0; i--, j++)//倒序存储
        b[j] = s2[i] - '0';

    if (d == 1)
    {
        Sleep(500);
        printf("-----操作数存储完毕\n");
    }

    for (i = 0; i < la; i++)//无进位竖式乘法
    {
        for (j = 0; j < lb; j++)
            c[i + j] += a[i] * b[j];
    }
    if (d == 1)
    {
        Sleep(500);
        printf("-----无进位计算开始\n");
    }
    for (i = 0; i <= la + lb; i++)//进位处理
    {
        c[i + 1] += c[i] / 10;
        c[i] %= 10;
    }
    if (d == 1)
    {

Sleep(500);
        printf("-----进位处理开始\n");
    }
    while (!c[i] && i >= 0)//输出位数计算
        i--;

    printf("计算结果为:");
    if (i == -1)
    {
        printf("0");
    }
    else
    {
        while (i >= 0)
            printf("%d", c[i--]);
    }
    free(a);
    free(b);
    free(c);
    if (d == 1)
        printf("\n-----内存空间释放完毕");
    system("pause");
}

猜你喜欢

转载自blog.csdn.net/kongming07/article/details/78690557