All pastes #974319 Raw Edit

Mine

public text v1 · immutable
·published 2008-04-06 18:49 UTC
rendered paste body
#include <iostream>
#include <map>

using std::map;
using std::ostream;

template<typename base_t, typename exp_t>
const base_t power(base_t x, exp_t n) {
        base_t r(1);
        while (n > exp_t(1)) {
                if (n % exp_t(2) == exp_t(1)) r *= x;
                n /= exp_t(2);
                x *= x;
        }
        return r*x;
}


template<typename base_t, typename exp_t>
class bignum_t {
        public:
                virtual ~bignum_t() {}
                bignum_t() : factors() {}

                bignum_t(const base_t & p) : factors() {
                        // FIXME: Needs to be factored first!!!
                        factors[p] = exp_t(1);
                }

                bignum_t(const base_t & p, const exp_t & e) : factors() {
                        // FIXME: Needs to be factored first!!!
                        factors[p] = e;
                }

                bignum_t(const bignum_t & rhs) : factors(rhs.factors) {}

                bignum_t & operator = (const base_t & p) {
                        // FIXME: Needs to be factored first!!!
                        if (this->factors.size()) this->factors.clear();
                        factors[p] = exp_t(1);
                        return *this;
                }

                bignum_t & operator = (const bignum_t & rhs) {
                        if (this->factors.size()) this->factors.clear();
                        this->factors = rhs.factors;
                        return *this;
                }

                friend ostream & operator << (ostream & lhs, \
                                              const bignum_t & rhs) {

                        for (typename map<base_t,exp_t>::const_iterator it=rhs.factors.begin();\
                               it != rhs.factors.end(); it++) {
                                if (it != rhs.factors.begin())
                                        lhs << "*";
                                lhs << it->first;
                                //if (it->second > exp_t(1) || it->second < exp_t(-1))
                                        lhs << "^" << it->second;
                        }
                        return lhs;
                }


                operator int32_t () {
                        int32_t numerator = 1, denominator = 1;
                        for (typename map<base_t,exp_t>::const_iterator it = this->factors.begin(); \
                                it != this->factors.end(); it++) {
                                if (it->second > 0)
                                        numerator *= (int32_t) power(it->first, it->second);
                                else
                                        denominator *= (int32_t) power(it->first, it->second);
                        }
                        return numerator / denominator;
                }

                operator double () {
                        double numerator = 1.0, denominator = 1.0;
                        for (typename map<base_t,exp_t>::const_iterator it = this->factors.begin(); \
                                it != this->factors.end(); it++) {
                                        if (it->second > 0)
                                                numerator *= (double) power(it->first, it->second);
                                        else
                                                denominator *= (double) power(it->first, it->second);
                        }
                        return numerator / denominator;
                }

                const bignum_t operator ~ () const {
                        bignum_t temp(*this);
                        for (typename map<base_t, exp_t>::iterator it = temp.factors.begin(); \
                                                it != temp.factors.end(); it++)
                                it->second *= exp_t(-1);
                        return temp;
                }

                const bignum_t & operator ^ (const base_t & rhs) const {
                        bignum_t temp(*this);
                        for (typename map<base_t, exp_t>::iterator it = temp.factors.begin(); \
                                it != temp.factors.end(); it++)
                                it->second *= rhs;
                        return temp;
                }

                const bignum_t operator / (const bignum_t & rhs) const {
                        return *this * ~rhs;
                }

                const bignum_t operator + (bignum_t addend2) const {
                        bignum_t res, temp, addend1(*this);
                        exp_t diff;

                        // First we copy all the common factors into temp
                        // so that our evaluation and subsequent factoring
                        // is minimized.
                        for (unsigned int j = 0; j < 2; j++) {
                                for (typename map<base_t, exp_t>::iterator it1 = \
                                     j ? addend2.factors.begin() : addend1.factors.begin() \
                                     , it2; it1 != addend1.factors.end(); it1++) {
                                        it2 = j ? addend1[it1->first] : addend2[it1->first];
                                        diff = exp_t(0);
                                        if (it1->second > 0 && it2->second > 0) {
                                                diff = (it1->second < it2->second) ? it1->second : it2->second;
                                        } else if (it1->second < 0 && it1->second < 0) {
                                                diff = (it1->second > it2->second) ? it1->second : it2->second;
                                                diff *= exp_t(-1);
                                        }
                                        if (diff != 0) {
                                                temp[it1->first] = diff;
                                                it1->second -= diff;
                                                it2->second -= diff;
                                        }
                                }
                        }

                        // Now we find the lcm and remove it from the addends
                        // and place it in the result

                        // Now we evaluate the numerator

                        // Now we just need to factor the numerator
                        // which is all the factors with positive exponents.
                        // ... Factorization goes here ...

                        // Finally we multiply what we originally factored
                        // out and return
                        return res * temp;
                }

                const bignum_t operator * (const bignum_t & rhs) const {
                        bignum_t temp(*this);

                        for (typename map<base_t, exp_t>::const_iterator it = \
                              rhs.factors.begin(); it != rhs.factors.end(); it++)
                                if ( ((bignum_t &) rhs).factors  [it->first])
                                        temp.factors[it->first] = it->second + \
                                               ((bignum_t &) *this).factors[it->first];

                        return temp;
                }

        protected:
                map<base_t, exp_t> factors;

};

typedef bignum_t<uint32_t, int32_t> bignum32;
typedef bignum_t<uint64_t, int32_t> bignum64;

using std::cout;
using std::endl;

int main() {

        bignum32 b2(5,2);
        bignum32 b(5,2);
        bignum32 b3 = b * b2;

        cout << (double) b3 << endl;

/*
        bignum32 b, b2, b3;

        srand(time(NULL));

        for (unsigned int i = 0; i < 1000; i++) {
                b  = rand() % 1000 + 500;
                b2 = rand() % 500  + 1;
                b3 = b / b2;
                //std::cout << (int32_t) (b3) << std::endl << std::endl;
        }
*/

        return 0;

}