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才能减

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

  • 相关阅读:
    内存对齐
    总结一下,一晃工作有一年了
    标准库中迭代器的关系
    反转迭代器和插入迭代器的区别
    MFC定时关机程序的实现3-最小化到托盘栏
    MFC定时关机程序的实现2-添加启动项到注册表
    MFC定时关机程序的实现1
    C++文件读写之对象的读写
    ADO之密码验证--3次错误就锁定『改进』
    ADO之密码验证--3次错误就锁定
  • 原文地址:https://www.cnblogs.com/SeanOcean/p/10975550.html
Copyright © 2011-2022 走看看