#include #include #include #include #include #include using namespace std; //Ways to improve perfromance: //1. Use char instead of int. --Done! //2. Improve the multiplication algorithm. I think that I can roughly //improve performance by roughly 50% by just changing the algorithm, //and other optimizations, and also using another (Vedic) //multiplication technique. The later technique would also result in //lesser memory consumption (I think!) class Long_Int { public: typedef char Rep_Type; std::vector _rep; //public: Long_Int () { } template Long_Int (const Int_Type& Value) { this->assign (Value); } template void assign (const Int_Type& Value) { Int_Type Temp = Value; _rep.clear(); while (Temp) { _rep.push_back (Temp % 10); Temp /= 10; } } template Long_Int& operator+= (const Int_Type& Value) { Long_Int Temp (Value); return *this += Temp; } Long_Int& operator-- () { std::vector::iterator Borrow = _rep.begin(); std::vector::iterator Curr = _rep.begin(); if (Curr != _rep.end()) { if (*Curr >= 1) { --*Curr; return *this; } else { Borrow = Curr + 1; while (Borrow != _rep.end()) { if (*Borrow > 0) { --*Borrow; if (Borrow == _rep.end() - 1 && *Borrow == 0) _rep.pop_back(); break; } else *Borrow = 9; ++Borrow; } *Curr = 9; } } return *this; } Long_Int& operator+= (const Long_Int& _li) { std::vector::iterator i1 = _rep.begin(); std::vector::const_iterator i2 = _li._rep.begin(); Rep_Type Carry = 0; while (i1 != _rep.end() && i2 != _li._rep.end()) { *i1 += (*i2 + Carry); if (*i1 > 9) { Carry = 1; *i1 -= 10; } else Carry = 0; ++i1; ++i2; } if (i1 == _rep.end()) { while (i2 != _li._rep.end()) { _rep.push_back (*i2 + Carry); if (_rep.back() > 9) { Carry = 1; _rep.back() -= 10; } else Carry = 0; ++i2; } } else { while (i1 != _rep.end()) { *i1 = (*i1 + Carry); if (*i1 > 9) { Carry = 1; *i1 -= 10; } else Carry = 0; ++i1; } } if (Carry) _rep.push_back (Carry); return *this; } Long_Int& operator*= (const Long_Int& _li) { //For multiplication, we should select the smaller of the 2 //Long_Ints, however, it will not work, since the 2nd one //(parameter) is const. Hence, we have to create as many Long_Ints //as there are entries in the 2nd Long_Int. std::vector Parts (_li._rep.size()); std::vector::size_type Index = 0; while (Index < Parts.size()) { Parts[Index] = *this; Parts[Index]._rep.insert (Parts[Index]._rep.begin(), Index, 0); Parts[Index].Multiply (_li._rep[Index]); ++Index; } Index = 0; this->assign (0); while (Index < Parts.size()) { *this += Parts[Index]; ++Index; } return *this; } template void Multiply (const Int_Type& Value) { assert (Value >= 0 && Value <= 9); std::vector::iterator i = _rep.begin(); Rep_Type Carry = 0; while (i != _rep.end()) { *i *= Value; *i += Carry; if (*i > 9) { Carry = *i / 10; *i %= 10; } else Carry = 0; ++i; } if (Carry) _rep.push_back (Carry); } friend std::ostream& operator<< (std::ostream&, const Long_Int&); friend std::istream& operator>> (std::istream&, const Long_Int&); friend bool operator< (const Long_Int&, const Long_Int&); friend bool operator> (const Long_Int&, const Long_Int&); friend bool operator== (const Long_Int&, const Long_Int&); friend bool operator!= (const Long_Int&, const Long_Int&); friend Long_Int operator* (const Long_Int&, const Long_Int&); }; Long_Int operator* (const Long_Int& _li1, const Long_Int& _li2) { Long_Int Temp = _li1; Temp *= _li2; return Temp; } bool operator< (const Long_Int& _li1, const Long_Int& _li2) { if (_li1._rep.size() < _li2._rep.size()) return true; else if (_li1._rep.size() > _li2._rep.size()) return false; std::vector::const_reverse_iterator i1 = _li1._rep.rbegin(); std::vector::const_reverse_iterator i2 = _li2._rep.rbegin(); while (i1 != _li1._rep.rend()) { if (*i1 < *i2) return true; ++i1; ++i2; } return false; } bool operator> (const Long_Int& _li1, const Long_Int& _li2) { if (_li1._rep.size() > _li2._rep.size()) return true; else if (_li1._rep.size() < _li2._rep.size()) return false; std::vector::const_reverse_iterator i1 = _li1._rep.rbegin(); std::vector::const_reverse_iterator i2 = _li2._rep.rbegin(); while (i1 != _li1._rep.rend()) { if (*i1 > *i2) return true; ++i1; ++i2; } return false; } bool operator== (const Long_Int& _li1, const Long_Int& _li2) { if (_li1._rep.size() != _li2._rep.size()) return false; std::vector::const_reverse_iterator i1 = _li1._rep.rbegin(); std::vector::const_reverse_iterator i2 = _li2._rep.rbegin(); while (i1 != _li1._rep.rend()) { if (*i1 != *i2) return false; ++i1; ++i2; } return true; } bool operator!= (const Long_Int& _li1, const Long_Int& _li2) { return !(_li1 == _li2); } std::ostream& operator<< (std::ostream& out, const Long_Int& _li) { // std::string Str (_li._rep.rbegin(), _li._rep.rend()); // out<::const_reverse_iterator i = _li._rep.rbegin(); while (i != _li._rep.rend()) out<(*i+48), ++i; return out; } std::istream& operator>> (std::istream& in, Long_Int& _li) { // std::basic_string > Str; // in>>Str; char Temp = 0; in.get (Temp); std::vector _trep; while (Temp != '\n') { _trep.push_back (Temp-48); in.get (Temp); } // cout<>li1; // // cout<<"The number Entered is: "<>li2; // // li1 *= li2; // // // li1.Multiply (100); // // cout<<"Their product is: "< T fac ( T num) { T temp = num; return num > 1 ? num * fac (--temp) : 1; } int main() { Long_Int li2 = fac (100); // Long_Int li2 = 2000; // --li2; cout << "Factorial of 100 is : "<< li2 << '\n'; return 0; }