• 高精度四则运算


     高精度运算,是指参与运算的数(加数,减数,因子……)范围大大超出了标准数据类型(整型,实型)能表示的范围的运算。例如,求两个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
        */
    }

     

  • 相关阅读:
    LeetCode 图解 | 200 .岛屿数量
    再不跳槽,应届毕业生拿的都比我多了!
    二叉树就是这么简单(面试常考点)
    我和面试官之间关于操作系统的一场对弈!写了很久,看完你就可以盘面试官了...
    非常详细的 Linux C/C++ 学习路线总结!助我拿下腾讯offer
    这款开源神器,让你能在 iPad 上随心所欲写代码!
    不瞒你说,我最近整理了一套面试题(Java岗)
    如何看待第三方百度云 Pandownload 作者被捕?
    【故事】为了避免产品经理和程序猿干架,我用大白话讲清楚了浏览器缓存原理...
    自己拥有一台服务器可以做哪些很酷的事情?搭建私有云网盘!
  • 原文地址:https://www.cnblogs.com/dandi/p/3501739.html
Copyright © 2020-2023  润新知