zoukankan      html  css  js  c++  java
  • 高精

    高精

    高精度计算中需要处理好以下几个问题:

    (1)数据的接收方法和存贮方法

    数据的接收和存贮:当输入的数很长时,可采用字符串方式输入,这样可输入数字很长的数,利用字符串函数和操作运算,将每一位数取出,存入数组中。另一种方法是直接用循环加数组方法输入数据。

    void init(int a[])                             //传入一个数组

    {

               string s;

           cin>>s;                                //读入字符串s

           a[0]=s.length();                  //a[0]计算字符串s的位数

           for(i=1;i<=a[0];i++)

              a[i]=s[a[0]-i]-'0';          //将数串s转换为数组a,并倒序存储

    }另一种方法是直接用循环加数组方法输入数据。

    (2) 高精度数位数的确定

       位数的确定:接收时往往是用字符串的,所以它的位数就等于字符串的长度。

    (3) 进位,借位处理

        加法进位:c[i]=a[i]+b[i];

                             if (c[i]>=10) { c[i]%=10; ++c[i+1]; }

      减法借位:if (a[i]<b[i]) { --a[i+1]; a[i]+=10; }

                             c[i]=a[i]-b[i];

      乘法进位:c[i+j-1]= a[i]*b[j] + x + c[i+j-1];

    x = c[i+j-1]/10;

                             c[i+j-1] %= 10;

    (4) 商和余数的求法

         商和余数处理:视被除数和除数的位数情况进行处理.

    第一节 高精加。

    【分析】竖式加法

    因此,算法描述如下:

    int c[100];

    void add(int a[],int b[])      //a,b,c都为数组,分别存储被加数、加数、结果

    {

        int  i=1,x=0;                           //x是进位

        while ((i<=a数组长度)||(i<=b数组的长度))

     {

        c[i]=a[i]+b[i]+x;     //i位相加并加上次的进位

        x=c[i]/10;              //向高位进位

        c[i]%=10;                       //存储第i位的值

        i++;                                //位置下标变量

     }

    }

    第二节 高精减

    【算法分析】竖式减法

     类似加法,可以用竖式减法。在做减法运算时,需要注意的是:被减数必须比减数大,同时需要处理借位。高精度减法的参考程序:

    cin>>st1>>st2;

    int len1=st1.size(),len2=st2.size(),i;

    FORa(i,1,len1) a[i]=st1[len1-i]-'0';

    FORa(i,1,len2) b[i]=st2[len2-i]-'0';

    FORa(i,1,len1)

    {

    a[i]=a[i]-b[i];

    if(a[i]<0) a[i]+=10,a[i+1]--;借位

    }

    while(!a[len1]&&len1>1)

    len1--;处理前导零

    FORs(i,len1,1) cout<<a[i];

     

    第三节 高精乘

    len=len1+len2+2;

    FORa(i,1,len1)

    {

    int x=0;

    FORa(j,1,len2)

    {

    c[i+j-1]+=a[i]*b[j]+x; 进位

    x=c[i+j-1]/10;      

    c[i+j-1]%=10;

    }

    if(x)

    c[i+len2]=x;

    }

    while(!c[len]&&len>1)

    len--; 前导零

    第四节 低精除

    FORa(i,1,len1)

    {

    s=s*10+a[i];

    if(s>b) break;寻找商一

    }

    c[++tot]=s/b,s%=b;

    FORa(i,i+1,len1)

    {

    s=s*10+a[i];

    c[++tot]=s/b;储存商

    s%=b;

    }余数即为最后的s

    【总结】:

    1. 乘法,减法的进位,借位,前导零
    2. 压位高精的第一位特殊处理,每一个单位的进位原则,注意:需要现将每一位乘上乘数,最后再考虑动态进位
    3. 高精减需要考虑最后一位,即只能len>1的时候,len才能减

    感谢各位与信奥一本通的鼎力相助!

  • 相关阅读:
    C#深入浅出 修饰符(二)
    HDU 5785 Interesting
    HDU 5783 Divide the Sequence
    HDU 5781 ATM Mechine
    UVA 714 Copying Books
    uva 1471 Defense Lines
    UVA 11134 Fabled Rooks
    UVA 11572 Unique Snowflakes
    UVA 11093 Just Finish it up
    UVA 10954 Add All
  • 原文地址:https://www.cnblogs.com/SeanOcean/p/10975550.html
Copyright © 2011-2022 走看看