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

     高精度运算,是指参与运算的数(加数,减数,因子……)范围大大超出了标准数据类型(整型,实型)能表示的范围的运算。例如,求两个200位的数的和。这时,就要用到高精度算法了。

    加减乘利用模拟竖式运算的方法很简单就可以实现。
    除法有点麻烦。
    关于除法,网上所说的做法一般有下面几种。
    1.枚举结果,利用乘法验证。
    2.不断使用减法。
    3.二分答案 他们都高大上地丢下一句二分答案,所以我就推测大概是第一种的优化版,二分枚举答案,范围为1..本身,然后利用乘法验证。

    1,2中显然时间复杂度十分高,为o(n*k1*k2)
    n为被除数的数字大小,k1*k2为两个数的位数。
    显然是十分不理想的算法。

    3.的话,就是logn*k1*k2
    虽然依然不好,但是优化了很不少了。
    然而用3的话还要先解决高精度数除以int的算法。

    下面给出高精度四则运算的代码。
    假如有对于除法更好的算法,请务必赐教。

     
    #include <iostream>

    #include <sstream>
    #include <string>
     
    #define rep(i,a,b) for (int i=a;i<=b;i++)
     
    using namespace std;
     
    const int N=1000;
     
    struct high_precision{
    int dat[N+1];
    int size;
    high_precision &operator=(high_precision a);
    high_precision (){
    size=0;
    memset(dat,0,sizeof(dat));
    }
    };
     
    istream &operator >>(istream&,high_precision&);
    ostream &operator <<(ostream&,high_precision);
    high_precision operator +(high_precision,high_precision);
    high_precision operator -(high_precision,high_precision);
    high_precision operator *(high_precision,high_precision);
    high_precision operator /(high_precision,int);
    bool operator >(high_precision,high_precision);
    bool operator <(high_precision,high_precision);
    bool operator ==(high_precision,high_precision);
     
    high_precision a,b;
     
    int main(){
    cin>>a>>b;
     
    cout<<"a+b="<<a+b<<endl;
    cout<<"a-b="<<a-b<<endl;
    cout<<"a*b="<<a*b<<endl;
    }
     
    istream &operator >>(istream &cin,high_precision &a){
    string str;
    stringstream ss;
    int n;
     
    cin>>str;
    a.size=0;
    while(str.length()>4){
    n=str.length();
    ss<<str.substr(n-4,4);
    ss>>a.dat[++a.size];
    ss.clear();
    str=str.substr(0,n-4);
    }
     
    ss<<str;
    ss>>a.dat[++a.size];
     
    return cin;
    }
     
    ostream &operator <<(ostream &cout,high_precision a){
    cout<<a.dat[a.size];
    for (int i=a.size-1;i>=1;i--){
    if (a.dat[i]<1000)
    if (a.dat[i]<100)
    if (a.dat[i]<10)
    cout<<"000";
    else cout<<"00";
    else cout<<"0";
    cout<<a.dat[i];
    }
    return cout;
    }
     
    high_precision operator +(high_precision a,high_precision b){
    a.size=max(a.size,b.size);
    rep(i,1,a.size){
    a.dat[i]+=b.dat[i];
    a.dat[i+1]+=a.dat[i]/10000;
    a.dat[i]%=10000;
    }
    if (a.dat[a.size+1])
    a.size++;
    return a;
    }
     
    high_precision operator -(high_precision a,high_precision b){
    //as there is no flag to show the number is positive or not
    //so we'got to assume that a is always bigger than b or it just will go wrong
    rep(i,1,a.size){
    a.dat[i]-=b.dat[i];
    if (a.dat[i]<0){
    a.dat[i]+=10000;
    a.dat[i+1]--;
    }
    }
    while(a.dat[a.size]==0)
    a.size--;
    return a;
    }
    high_precision operator *(high_precision a,high_precision b){
    high_precision c;
    c.size=a.size+b.size;
     
    rep(i,1,a.size)
    rep(j,1,b.size)
    c.dat[i+j-1]+=a.dat[i]*b.dat[j];
    rep(i,1,c.size)
    if (c.dat[i]>10000){
    c.dat[i+1]+=c.dat[i]/10000;
    c.dat[i]%=10000;
    }
    while(c.dat[c.size]==0)
    c.size--;
    return c;
    }
     
    high_precision operator /(high_precision a,int b){
    int c(0);
    for (int i=a.size;i>=1;i--){
    c=c*10000+a.dat[i];
    a.dat[i]=c/b;
    c%=b;
    }
    while(a.dat[a.size]==0)
    a.size--;
    return a;
    }
     
    bool operator >(high_precision a,high_precision b){
    if (a.size>b.size)
    return 1;
    else if (a.size<b.size)
    return 0;
    for (int i=a.size;i>=1;i--)
    if (a.dat[i]>b.dat[i])
    return 1;
    else if (a.dat[i]<b.dat[i])
    return 0;
    return 0;
    }
     
    bool operator ==(high_precision a,high_precision b){
    if (a.size!=b.size)
    return 0;
    rep(i,1,a.size)
    if (a.dat[i]!=b.dat[i])
    return 0;
    return 1;
    }
     
    bool operator <(high_precision a,high_precision b){
    if ((a>b) || (a==b))
    return 0;
    return 1;
    }
     
    high_precision &high_precision::operator=(high_precision a){
    this->size = a.size;
        rep(i,1,this->size)
        this->dat[i]=a.dat[i];
        return *this;
        /*
         remove all "this->" and don't return anything
         it works too
        */
    }

     

  • 相关阅读:
    包含游标、数组的例子
    团队开发的注意点
    养成逻辑的习惯
    C# DEV 右键出现菜单
    C#中ToString数据类型格式大全 千分符(转)
    Oracle系统查询的语句
    PLSQLDevelop 查询当前未完成的会话
    Oracle 异常工作中出现的
    Oracle 返回结果集 sys_refcursor
    DevExpress.XtraEditors.TextEdit,设定为必须number类型的。
  • 原文地址:https://www.cnblogs.com/dandi/p/3501739.html
Copyright © 2011-2022 走看看