高精度重载运算符模板

2017年3月21日 | ljfcnyali
高精度重载运算符一直是很多人入门的基础,我也不例外。
这么久的努力奋斗以来,突然发现自己连一个高精度重载运算符的模板都没有打,立刻开始敲键盘。
这个高精度重载运算符其实很简单,会使用”operator”的就会,不会也没有任何办法。
所以,我决定不写方法,也就仅仅贴一个代码,给理解了”operator”的各位一个可以仿照的模板。
保证正确(但是除法最后不想谢了,250行的代码那么好些么,所以没有写除法,敬请谅解),经过实验(代码中就有)。
代码如下:

/*************************************************************************
    > File Name: 模板\高精度模板.cpp
    > Author: ljf-cnyali
    > Mail: ljfcnyali@gmail.com 
    > Created Time: 2017/3/21 19:28:59
 ************************************************************************/

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<queue>

using namespace std;

#define REP(i, a, b) for(int i = (a), _end_ = (b);i <= _end_; ++ i)
#define mem(a) memset((a), 0, sizeof(a))
#define str(a) strlen(a)

const int maxn = 9999;
const int Dlen = 5;
const int MaxSize = 10;

typedef long long Huge;

struct BigNum {
private :
    int len, a[500];
public :
    BigNum() {
        len = 1;
        mem(a);
    }
    BigNum(const int);
    BigNum(const char*);
    BigNum(const BigNum &);
    BigNum &operator = (const BigNum &);

    friend istream& operator >> (istream &, BigNum &);
    friend ostream& operator << (ostream &, BigNum &);

    BigNum operator + (const BigNum &) const;
    BigNum operator * (const BigNum &) const;
    BigNum operator - (const BigNum &) const;

    bool operator > (const BigNum & T) const;
    bool operator > (const int & t) const;

    void print();
};

BigNum::BigNum(const int x) {
    int u, v = x;
    len = 0;
    mem(a);
    while(v > maxn) {
        u = v - (v / (maxn + 1) * (maxn + 1));
        v = v / (maxn + 1);
        a[len ++] = u;
    }
    a[len ++] = v;
}

BigNum::BigNum(const char*s) {
    int t, k, index, l;
    mem(a);
    l = str(s);
    len = l / Dlen;
    if(l % Dlen)
        ++ len;
    index = 0;
    for(int i = l - 1; i >= 0; i -= Dlen) {
        t = 0;
        k = i - Dlen + 1;
        if(k < 0)
            k = 0;
        REP(j, k, i)
            t = t * 10 + s[j] - '0';
        a[index ++] = t;
    }
}

BigNum::BigNum(const BigNum &T) : len(T.len) {
    memcpy(a, T.a, len * sizeof * a);
}

BigNum & BigNum:: operator = (const BigNum & n) {
    len = n.len;
    memcpy(a, n.a, len * sizeof * a);
    return *this;
}

istream& operator >> (istream & in, BigNum & b) {
    char c[MaxSize * 4];
    int i = -1;
    in >> c;
    int l = str(c);
    int count = 0, sum = 0;
    for(i = l - 1; i >= 0; ) {
        sum = 0;
        int t = 1;
        for(int j = 0; j < 4 && i >= 0; ++ j, -- i, t *= 10) 
            sum += (c[i] - '0') * t;
        b.a[count ++] = sum;
    }
    b.len = count ++;
    return in;
}

ostream& operator << (ostream& out, BigNum& b) {
    int i;
    cout << b.a[b.len - 1];
    for(i = b.len - 2; i >= 0; -- i) {
        cout.width(Dlen);
        cout.fill(0);
        cout << b.a[i];
    }
    return out;
}

BigNum BigNum:: operator + (const BigNum & T) const {
    BigNum t(*this);
    REP(i, 0, T.len > len ? T.len : len) {
        t.a[i] += T.a[i];
        if(t.a[i] > maxn) {
            t.a[i + 1] ++;
            t.a[i] -= maxn + 1;
        }
    }
    int num = T.len > len ? T.len : len;
    if(t.a[num] != 0)
        t.len = num + 1;
    else
        t.len = num;
    return t;
}

BigNum BigNum::operator - (const BigNum  & T) const {
    int num;
    bool flag;
    BigNum t1, t2;
    if(*this > T) {
        t1 = *this;
        t2 = T;
        flag = 0;
    }
    else {
        t1 = T;
        t2 = *this;
        flag = 1;
    }
    num = t1.len;
    int j;
    REP(i, 0, num - 1) 
        if(t1.a[i] < t2.a[i]) {
            j = i + 1;
            while(t1.a[j] == 0)
                ++ j;
            t1.a[j --] --;
            while(j > i)
                t1.a[j --] += maxn;
            t1.a[i] += maxn + 1 - t2.a[i];
        }
        else 
            t1.a[i] -= t2.a[i];
    t1.len = num;
    while(t1.a[len - 1] == 0 && t1.len > 1) {
        t1.len --;
        num --;
    }
    if(flag) 
        t1.a[num - 1] = 0 - t1.a[num - 1];
    return t1;
}

BigNum BigNum::operator * (const BigNum & T) const {
    BigNum ret;
    int up, temp, temp1, j, i;
    for(i = 0; i < len; ++ i) {
        up = 0;
        for(j = 0; j < T.len; ++ j) {
            temp = a[i] * T.a[j] + ret.a[i + j] + up;
            if(temp > maxn) {
                temp1 = temp - temp / (maxn + 1) * (maxn + 1);
                up = temp / (maxn + 1);
                ret.a[i + j] = temp1;
            }
            else {
                up = 0;
                ret.a[i + j] = temp;
            }
        }
        if(up != 0)
            ret.a[i + j] = up;
    }
    ret.len = i + j;
    while(ret.a[ret.len - 1] == 0 && ret.len > 1)
        ret.len --;
    return ret;
}

bool BigNum::operator > (const BigNum & T) const { 
    int ln; 
    if(len > T.len)
        return true; 
    else if(len == T.len) { 
        ln = len - 1; 
        while(a[ln] == T.a[ln] && ln >= 0)
            ln --; 
        if(ln >= 0 && a[ln] > T.a[ln])
            return true; 
        else
            return false; 
    } 
    else
        return false; 
}
bool BigNum::operator > (const int & t) const {
    BigNum b(t);
    return *this > b;
}

void BigNum::print() { 
    int i;   
    cout << a[len - 1]; 
    for(i = len - 2 ; i >= 0 ; -- i){ 
        cout.width(Dlen); 
        cout.fill('0'); 
        cout << a[i]; 
    } 
    cout << endl;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    BigNum x[101];
    x[0] = 1;
    int n;
    REP(i, 1, 100)
        x[i] = x[i - 1] * (i + 2 - 2);
    REP(i, 1, 100)
        x[i].print();
    return 0;
}

本文转自:http://ljf-cnyali.cn/index.php/archives/96

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值