#include <iostream>
#include <iomanip>
#include <vector>
#define DEC
struct integer{
private:
bool negative;
std::vector<char> digit;
void add(unsigned int pos, unsigned int val){
if(pos >= digit.size()) digit.insert(digit.end(), pos-digit.size()+1, 0);
#ifdef DEC
if(digit[pos] + val >= 10){
add(pos+1, 1);
digit[pos] += val-10;
}else digit[pos] += val;
#else
if(digit[pos] > (unsigned int)(0-val)) add(pos+1, 1);
digit[pos] += val;
#endif
}
void sub(unsigned int pos, unsigned int val){
#ifdef DEC
if(digit[pos] < val){
sub(pos+1, 1);
digit[pos] -= val-10;
}else digit[pos] -= val;
#else
if(digit[pos] < val) sub(pos+1, 1);
digit[pos] -= val;
#endif
if(digit[pos] == 0 && pos+1 == digit.size()) digit.pop_back();
}
bool abs_greater(const integer& i) const{
if(digit.size() != i.digit.size()) return digit.size() > i.digit.size();
for(int k = digit.size()-1; k >= 0; k--)
if(digit[k] != i.digit[k]) return digit[k] > i.digit[k];
return 0;
}
public:
integer(int i){
if(negative = i < 0) digit.push_back(-i);
else digit.push_back(i);
}
integer(){}
friend integer operator * (const integer&, const integer&);
friend integer operator + (integer, integer);
friend integer operator - (integer, integer);
friend std::ostream& operator << (std::ostream&, const integer&);
friend std::istream& operator >> (std::istream&, integer&);
friend bool operator == (const integer&, const integer&);
friend bool operator != (const integer&, const integer&);
friend bool operator > (const integer&, const integer&);
friend bool operator <= (const integer&, const integer&);
friend bool operator < (const integer&, const integer&);
friend bool operator >= (const integer&, const integer&);
integer operator = (const integer& i){
digit = i.digit;
negative = i.negative;
return i;
}
integer operator += (const integer& i){
*this = *this + i;
return *this;
}
integer operator -= (const integer& i){
*this = *this - i;
return *this;
}
integer operator *= (const integer& i){
*this = *this * i;
return *this;
}
integer operator /= (const integer& i){
*this = *this / i;
return *this;
}
integer operator -(){
integer i = *this;
i.negative = !i.negative;
return i;
}
};
integer operator + (integer a, integer b){
if(a.negative == b.negative){
for(unsigned int k = 0; k < b.digit.size(); k++)
a.add(k, b.digit[k]);
}else{
if(b.abs_greater(a)) std::swap(a, b);
for(unsigned int k = 0; k < b.digit.size(); k++)
a.sub(k, b.digit[k]);
}
return a;
}
integer operator - (integer a, integer b){
return a + (-b);
}
integer operator * (const integer& a, const integer& b){
integer r;
r.negative = a.negative ^ b.negative;
for(unsigned int j = 0; j < a.digit.size(); j++)
for(unsigned int k = 0; k < b.digit.size(); k++){
#ifdef DEC
char val = a.digit[j]*b.digit[k];
if(val >= 10) r.add(j+k+1, val/10);
r.add(j+k, val%10);
#else
unsigned long long int val = a.digit[j];
val *= b.digit[k];
if(val >> 32 > 0)
r.add(j+k+1, val>>32);
r.add(j+k, (unsigned int)val);
#endif
}
return r;
}
bool operator == (const integer& a, const integer& b){
if(a.negative != b.negative || a.digit.size() != b.digit.size()) return false;
for(int i = a.digit.size() -1; i >= 0; i--)
if(a.digit[i] != b.digit[i]) return false;
return true;
}
bool operator != (const integer& a, const integer& b){
return !(a==b);
}
bool operator > (const integer& a, const integer& b){
if(a.negative ^ b.negative) return !a.negative;
return a.abs_greater(b) ^ a.negative;
}
bool operator < (const integer& a, const integer& b){
return !(a>b || a==b);
}
bool operator >= (const integer& a, const integer& b){
return a>b || a==b;
}
bool operator <= (const integer& a, const integer& b){
return !(a>b);
}
std::ostream& operator << (std::ostream& out, const integer& i){
if(i.negative) out.put('-');
#ifdef DEC
for(int k = i.digit.size() -1; k >= 0; k--) out.put('0'+i.digit[k]);
if(i.digit.size() == 0) out.put('0');
#else
const char d[] = "0123456789abcdef";
bool first = true;
for(int k = i.digit.size() -1; k >= 0; k--){
for(int j = 8-1; j >= 0; j--){
char ch = (i.digit[k] >> j*4) & 0xf;
if(ch != 0) first = false;
if(!first || ch != 0) out.put( d[ch] );
}
}
#endif
return out;
}
std::istream& operator >> (std::istream& in, integer& i){
in >> std::ws;
i.negative = 0;
if(in.peek() == '-') i.negative = 1;
if(in.peek() == '+' || in.peek() == '-') in.get();
#ifdef DEC
while(1){
char c = in.peek();
if(c >= '0' && c <= '9') i.digit.push_back(in.get() - '0');
else break;
}
for(int k = 0; k*2 < i.digit.size()-1; k++) std::swap(i.digit[k], i.digit[i.digit.size()-1-k]);
#else
std::vector<char> vec;
while(1){
char c = in.peek(), i;
if(c >= '0' && c <= '9') i = c - '0';
else if(c >= 'a' && c <= 'f') i = c - 'a' + 10;
else if(c >= 'A' && c <= 'F') i = c - 'A' + 10;
else break;
in.get();
vec.push_back(i);
}
i.digit.clear();
for(int k = vec.size() -1, m = 0, s = 0; k >= 0; k--){
s += vec[k] << m*4;
if(m == 7 || k == 0){
i.digit.push_back(s);
s = m = 0;
}else m++;
}
#endif
return in;
}
int main(){
integer i = 1;
integer j;
std::cout << "Enter a decimal number.\n";
std::cin >> j;
for(integer k = j; k > 0; k -= 1) i *= k;
std::cout << j << "! = " << i;
std::cin.ignore().get();
return 0;
}