• [模板]大整数相加、相乘


    欢迎测试!

    /*
        大整数 C 模版 (大整数相加,相乘) 
        字符串形式输入,s[0]为最高位
        
        author : http://www.cnblogs.com/JMDWQ/
    */
    
    # include <stdio.h>
    # include <string.h>
    
    # define MAXN (10000 + 5)                   /* MAXN -- 输入中整数的最大位数 */
    
    char a[MAXN], b[MAXN], c[2 * MAXN];
    
     int    bign_prep(char *s);
    void    str_rev(char *s);
     int    bign_cmp(char *a, char *b);
    void    Add(char *a, char *b, char *c);
     int    Sub(char *a, char *b, char *c);
    void    Mul(char *a, char *b, char *c);
    void    cal(char *a, char *b, char *c, char op);
    
    int main()
    {
        char opd[5];
        while (~scanf("%s%s%s", a, opd, b))
            cal(a, b, c, opd[0]);
        
        return 0;
    }
    
    /* 处理大整数前的负号,并返回大整数的符号 */
    int bign_prep(char *s)
    {
        int i;
        if (s[0] != '-')
        {
            for (i = 0; s[i]; ++i)
                if (s[i] != '0') return 1;
            return 0;
        }
        for (i = 0; s[i]; ++i)
            s[i] = s[i+1];
        return -1;
    }
    
    /* 字符串反转,s 末尾必须是 '\0' */
    void str_rev(char *s)
    {
        char ch;
        int i, n, len = strlen(s);
        n = len >> 1;
        for (i = 0; i < n; ++i)
            ch = s[i], s[i] = s[len-1-i], s[len-1-i] = ch;
    }
    /* 两个无符号大整数相比较, 返回 a-b 的符号,a==b 时返回 0 */
    int bign_cmp(char *a, char *b)
    {
        int i, lenx = strlen(a), leny = strlen(b);
        if (lenx > leny) return 1;
        if (lenx < leny) return -1;
        for (i = 0; i < lenx; ++i)
            if (a[i] > b[i])
                return 1;
            else if (a[i] < b[i])
                return -1;
        return 0;
    }
    
    /* 无符号大整数相加, c = a+b */
    void Add(char *a, char *b, char *c)
    {
        int i, tmp, ea = 1, eb = 1, carry = 0;
        str_rev(a), str_rev(b);
        for (i = 0; a[i]||b[i]; ++i)
        {
            if (!a[i]) ea = 0;
            if (!b[i]) eb = 0;
            tmp = carry;
            if (ea) tmp += a[i]-'0';
            if (eb) tmp += b[i]-'0';
            c[i]  = tmp % 10 + '0';
            carry = tmp / 10;
        }
        if (carry) c[i++] = carry+'0';
        while (--i && c[i] == '0') ;
        c[i+1] = '\0';
        str_rev(a), str_rev(b), str_rev(c);
    }
    
    /* c = abs(a-b), 返回 a-b 的符号, a==b时返回0,此时 c == "0" */
    int Sub(char *a, char *b, char *c)
    {
        char *p, *q;
        int i, n, tmp, sgnc, eq = 1, carry = 0;
        sgnc = bign_cmp(a, b);
        if (sgnc == 0) {c[0] = '0', c[1] = '\0'; return 0;}
        else if (sgnc > 0) p = a,q = b;
        else p = b, q = a;
        str_rev(a), str_rev(b);
        for (i = 0; p[i]||q[i]; ++i)
        {
            tmp = p[i]-'0'-carry;
            if (!q[i]) eq = 0;
            if (eq) tmp -= (q[i]-'0');
            if (tmp < 0) carry = 1;
            else carry = 0;
            c[i] = (tmp+10)%10+'0';
        }
        while (--i && c[i] == '0') ;
        c[i+1] = '\0';
        str_rev(a), str_rev(b), str_rev(c);
        return sgnc;
    }
    /* 无符号大整数相乘 */
    void Mul(char *a, char *b, char *c)
    {
        int i, j, tmp, lenx = strlen(a), leny = strlen(b);
        str_rev(a), str_rev(b);
        memset(c, 0, sizeof(char)*(lenx+leny));
        for (i = 0; a[i]; ++i)
        for (j = 0; b[j]; ++j)
        {
            tmp = c[i+j]+(a[i]-'0')*(b[j]-'0');
            c[i+j+1] += tmp/10;
            c[i+j] = tmp%10;
        }
        for (i = lenx+leny-1; !c[i]; --i) ;
        c[i+1] = '\0';
        for (; i >= 0; --i) c[i] += '0';
        str_rev(a), str_rev(b), str_rev(c);
    }
    /* 模拟大数计算器(加法和乘法),直接输出计算结果 */
    void cal(char *a, char *b, char *c, char op)
    {
        int op_sgn, sgna, sgnb, sub_sgn;
        sgna = bign_prep(a);
        sgnb = bign_prep(b);
        if (op == '+' || op == '-')
        {
            op_sgn = (op=='-' ? -1:1);
            if (op_sgn*sgna*sgnb > 0)
            {
                Add(a, b, c);
                if (sgna < 0) putchar('-');
                puts(c);
            }
            else
            {
                sub_sgn = Sub(a, b, c);
                if (sub_sgn*sgna < 0) putchar('-');
                puts(c);
            }
        }
        else if (op == '*')
        {
            Mul(a, b, c);
            if (sgna*sgnb < 0) putchar('-');
            puts(c);
        }
    }

     使用long long测的,测试程序

    下面的没包含负号,整数前包含负号的情况测过了,这个是之前的数据。

    /*************************sample**************************/

    input

    =====

    1 - 2
    45 - 2
    100 - 100
    1000 - 1000
    1000 - 10000
    999 - 999999
    1 + 2
    45 + 2
    100 + 100
    1000 + 1000
    1000 + 10000
    999 + 999999
    1 * 2
    45 * 2
    100 * 100
    1000 * 1000
    1000 * 10000
    999 * 999999

    =====

    output

    =====
    -1
    43
    0
    0
    -9000
    -999000
    3
    47
    200
    2000
    11000
    1000998
    2
    90
    10000
    1000000
    10000000
    998999001

    =====
    Used: 10 ms, 1448 KB

    /*********************************************************/

  • 相关阅读:
    js数组求交集
    php安装oci8和pdo_oci扩展实现连接oracle数据库
    nginx配置静态资源压缩
    SHELL递归遍历文件夹下所有文件
    PHP函数获取临时文件目录
    php去除文件bom头
    tcpdump抓取udp报文
    linux获取当前运行级别
    当安装软件后提示依赖没有安装时
    Ubuntu卸载通过apt-get命令安装的软件
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2630535.html
Copyright © 2020-2023  润新知