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

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

  • 相关阅读:
    查找list中的重复数据,并得到不重复数据索引位置
    sql server 存储过程中使用事务
    C#获取web.config配置文件内容
    SendKeys.Send 方法
    C# 获取当前路径方法(转载)
    asp.net中URL参数传值中文乱码的三种解决办法
    无法 连接到SQLEXPRESS 已成功与服务器建立连接,但是在登录过程中发生错误。管道的另一端无任何进程
    Windows7 IIS7 无法启动计算机上的服务W3SVC如何修复,计算机上无法找到.was解决方案 visita iis 7.0
    EXCEL开发Interior.ColorIndex 色彩列表
    asp.net web 登录文本框的回车设计
  • 原文地址:https://www.cnblogs.com/SeanOcean/p/10975550.html
Copyright © 2011-2022 走看看