zoukankan      html  css  js  c++  java
  • 高精度运算

    VonGang原创,如有错误,欢迎指正。转载请注明:http://www.cnblogs.com/vongang/

                                                                                                                                                   

                                                                                                                                               

                                                                                                                                                

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



  • 相关阅读:
    Python编程第5讲—if 语句
    GIT 笔记
    jQuery多余文字折叠效果
    静态库与动态库的制作与使用
    Makefile
    C++ 有理数类
    使用mstest.exe 命令行跑test case(不安装Visual Studio 2010)
    Termp Folder and its subfolders
    ToString() 格式化字符串总结
    REST基础
  • 原文地址:https://www.cnblogs.com/vongang/p/2143303.html
Copyright © 2011-2022 走看看