• 高精度计算


    当对很大的数(比如100位)进行运算时,肯定不能c/c++内的数据类型直接运算(当然Java里的BigNumber可以。。。)这时就要用数组模拟运算过程。+, - ,*, /,运算貌似是小学学的东西,童鞋们,现在要用到小学的知识啦!!
    先说加法,大体的操作包括逆序、对位、求和、进位(其实就是小学的加法运算,不过是把数倒过来算,至于为什么要逆序。。。)

    例题:http://poj.grids.cn/practice/2981

    代码:

    #include <stdio.h>
    #include <string.h>
    #define MAX 200
    int an1[MAX+10];
    int an2[MAX+10];
    char s1[MAX+10];
    char s2[MAX+10];
    int main()
    {
        scanf("%s", s1);
        scanf("%s", s2);
        int i, j;
        memset( an1, 0, sizeof(an1));
        memset( an2, 0, sizeof(an2));
        int len1 = strlen( s1);
        j = 0;
        for( i = len1 - 1;i >= 0 ; i --)        //逆置
            an1[j++] = s1[i] - '0';
        int len2 = strlen(s2);
        j = 0;
        for( i = len2 - 1;i >= 0 ; i --)          //逆置
            an2[j++] = s2[i] - '0';
        len1 = len1 > len2 ? len1 : len2;
        for( i = 0;i < len1 ; i ++ )
        {
            an1[i] += an2[i];    //求和
            if( an1[i] >= 10 )    //进位
            {
                an1[i] -= 10;
                an1[i+1] ++;
            }
        }
        int flag = 0;
        for (i = len1 ; i >= 0; i--)   //输出
        {
            if (flag || an1[i])
            {
                flag = 1;
                printf("%d",an1[i]);
            }
        }
        if (!flag)
        {
            printf("0");
        }
        printf("\n");
        return 0;
    }

    减法同加法类似

    例题:http://poj.grids.cn/practice/2736

    代码:

    #include <stdio.h>
    #include <string.h>
    #define MAX 200
    int an1[MAX+10];
    int an2[MAX+10];
    char s1[MAX+10];
    char s2[MAX+10];
    int main()
    {
        int i, j;
        int n;
        scanf("%d",&n);
        while(n--)
        {
            scanf("%s", s1);
            scanf("%s", s2);
            memset( an1, 0, sizeof(an1));
            memset( an2, 0, sizeof(an2));
            int len1 = strlen( s1);
            j = 0;
            for( i = len1 - 1;i >= 0 ; i --)
                an1[j++] = s1[i] - '0';
            int len2 = strlen(s2);
            j = 0;
            for( i = len2 - 1;i >= 0 ; i --)
                an2[j++] = s2[i] - '0';
            for( i = 0;i < len1 ; i ++ )
            {
                an1[i] -= an2[i];
                if( an1[i] < 0 )
                {
                    an1[i] += 10;
                    an1[i+1] --;
                }
            }
            int flag = 0;
            for (i = len1 ; i >= 0; i--)
            {
                if (flag || an1[i])
                {
                    flag = 1;
                    printf("%d",an1[i]);
                }
            }
            if (!flag)
            {
                printf("0");
            }
            if(n != 0)
                printf("\n");
        }
        printf("\n");
        return 0;
    }

    乘法同加法类似,不过进位时mod10而不是 -10:

    例题:http://poj.grids.cn/practice/2980

    代码:

    #include <stdio.h>
    #include <string.h>
    #define max 200
    int an1[max+10];
    int an2[max+10];
    int result[max*2+10];
    char s1[max+10];
    char s2[max+10];
    int main()
    {
        gets(s1);
        gets(s2);
        int i, j;
        memset(an1,0,sizeof(an1));
        memset(an2,0,sizeof(an2));
        memset(result,0,sizeof(result));
        int len1 = strlen(s1);
        j = 0;
        for(i = len1-1; i >= 0; i--)
            an1[j++] = s1[i] - '0';
        int len2 = strlen(s2);
        j = 0;
        for(i = len2-1; i >= 0; i--)
            an2[j++] = s2[i] - '0';
        for(i = 0; i < len2; i++)
            for(j = 0; j < len1; j++)
                result[i+j] += an2[i]*an1[j];
        for(i = 0; i < len1*len2; i++)
        {
            if(result[i] >= 10)
            {
                result[i+1] += result[i]/10;
                result[i] %= 10;
            }
        }
        int flag = 0;
        for(i = len1*len2; i >= 0; i--)
        {
            if(flag)
                printf("%d",result[i]);
            else if(result[i])
            {
                printf("%d",result[i]);
                flag = 1;
            }
        }
        if(!flag)
            printf("0");
        printf("\n");
        return 0;
    }

    除法:

    除法可以看作是循环相减,不过在做减法之前有一个判断两数大小的操作;

    还是例题:http://poj.grids.cn/practice/2737
    代码:

    #include <stdio.h>
    #include <string.h>
    #define max 200
    char s1[max + 10];
    char s2[max + 10];
    int an1[max + 10];
    int an2[max + 10];
    int result[max + 10];
    int jianfa(int a[], int b[], int len1, int len2)
    {
        int i;
        if(len1 < len2)    //----------以下判断大小-------------
            return -1;
        int flag = 0;
        if(len1 == len2)
        {
            for(i = len1 - 1; i >= 0; i--)
            {
                if(a[i] > b[i])
                    flag = 1;
                else if(a[i] < b[i])
                {
                    if(!flag)    return -1;
                }
            }
        }                         //-------------以上判断大小-------------
        for(i = 0; i < len1; i++)//减法
        {
            a[i] -= b[i];
            if(a[i] < 0)
            {
                a[i] += 10;
                a[i+1]--;
            }
        }
        for(i = len1 - 1; i >= 0; i--)
            if(a[i])
                return i+1;
        return 0;
    }
    int main()
    {
        int i, j, n;
        scanf("%d",&n);
        while(n--)
        {
            scanf("%s",s1);
            scanf("%s",s2);
            memset(an1, 0, sizeof(an1));
            memset(an2, 0, sizeof(an2));
            memset(result, 0, sizeof(result));
            int len1 = strlen(s1);
            j = 0;
            for(i = len1 - 1; i >= 0; i--)
                an1[j++] = s1[i] - '0';
            int len2 = strlen(s2);
            j = 0;
            for(i = len2 - 1; i >= 0; i--)
                an2[j++] = s2[i] - '0';
            if(len1 < len2)
            {
                printf("0\n");
                continue;
            }
            len1 = jianfa(an1, an2, len1, len2);
            if(len1 < 0)
            {
                printf("0\n");
                continue;
            }
            else if(len1 == 0)
            {
                printf("1\n");
                continue;
            }
            result[0]++; //减掉一次,商加1
            //减去一次后结果的长度是len1
            int n = len1 - len2;
            if(n < 0) //不能再减时
            {
                for(i = 0;i < max; i++)
                {
                    if(result[i] >= 10)
                    {
                        result[i+1] += result[i]/10;
                        result[i] %= 10;
                    }
                }
            }
            else if(n > 0)
            {
                for(i = len1 - 1; i >= 0; i--)
                {
                    if(i >= n)
                        an2[i] = an2[i-n];
                    else
                        an2[i] = 0;
                }
            }
            len2 = len1;
            for(j = 0; j <= n; j++)
            {
                int t;
                while((t = jianfa(an1, an2+j, len1, len2-j)) >= 0)
                // an2+j 表示把数组的头指针向后移j个位置,即删掉j个an2补上的0
                // len2 同时减小j
                {
                    len1 = t;
                    result[n-j]++;
                }
            }
            for(i = 0;i < max; i++)//进位
            {
                if(result[i] >= 10)
                {
                    result[i+1] += result[i]/10;
                    result[i] %= 10;
                }
            }
            int flag = 0;
            for(i = max; i >= 0; i--)//输出
                if(flag)
                    printf("%d",result[i]);
                else if(result[i])
                {
                    printf("%d",result[i]);
                    flag = 1;
                }
            if(!flag)
                printf("0\n");
            printf("\n");
        }
        return 0;
    }

    ps 转自http://www.cnblogs.com/vongang/

  • 相关阅读:
    Linux基础之计算机硬件
    python中 __cmp__
    python中 __str__和__repr__
    python的构造函数传入任意数量的参数
    python中的偏函数
    javascript正则表达式
    js实现复选框的全选、全部选和反选
    js中的函数对象
    js中的作用域
    js中的arguments
  • 原文地址:https://www.cnblogs.com/timeship/p/2622310.html
Copyright © 2020-2023  润新知