高精度计算

当对很大的数(比如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/

你可能感兴趣的:(计算)