#include<iostream>
#include<cstdlib>
#include<cstring>

class Numero {
	private:
		char* dig;
		int   nd;

	public:
		Numero(const char* n="0");
		Numero(const Numero&);
		Numero(int t);
		~Numero(void);
		int   ndig(void) const { return nd; };
		void  normal(void);
		char  operator [] (int k) const;
		char& operator [] (int k) { return dig[k]; };
		Numero& operator = (const Numero&);
};

Numero operator + (const Numero& a, const Numero& b);
Numero operator * (const Numero& a, const Numero& b);
std::ostream& operator << (std::ostream& out, const Numero& n);


Numero::Numero(const char* n)
{
	nd= strlen(n);
	dig= new char[nd];
	for (int i=0, k=nd-1; k>=0; --k, ++i)
		dig[i]= n[k]-'0';	
}

Numero::Numero(int t)
{
	nd= t;
	dig= new char[t];
	for (int i=0; i<t; ++i)
		dig[i]= 0;	
}

Numero::Numero(const Numero& a)
{
	nd= a.ndig();
	dig= new char[nd];
	for (int k=0; k<nd; ++k)
		dig[k]= a[k];
}

Numero& Numero::operator = (const Numero& n)
{
	delete [] dig;
	nd= n.ndig();
	dig= new char [nd];	
	for (int k=0; k<nd; ++k)
		dig[k]= n[k];
	return *this;
}

Numero::~Numero(void)
{
	delete [] dig;
	nd= 0;
}

void Numero::normal(void)
{
	int k= nd-1;
	while (k>0 && dig[k]==0)
		--k;
	nd= k+1;
}

char  Numero::operator [] (int k) const 
{ 
	return k<nd ? dig[k] : 0; 
};

std::ostream& operator << (std::ostream& out, const Numero& n)
{
	for (int k=n.ndig()-1; k>=0; --k)
		out << char(n[k]+'0');
	return out;
}

Numero operator + (const Numero& a, const Numero& b)
{
	int nda= a.ndig();
	int ndb= b.ndig();
	int nr= nda >= ndb ? nda : ndb;
	Numero r(nr+1);

	int acarreo=0;
	for (int k=0; k<nr; ++k) {
		int t= a[k] + b[k] + acarreo;
		if (t>=10) {
			acarreo= 1;
			t-= 10;
		}
		else
			acarreo= 0;
		r[k]= t;
	}
	r[nr]= acarreo;
	r.normal();
	return r;
}


Numero operator * (const Numero& a, const Numero& b)
{
	Numero r;
	int nda= a.ndig();
	int ndb= b.ndig();
	for (int i=0; i<ndb; ++i) {
		Numero p(a.ndig()+1+i);
		int m= b[i];
		int c= 0;
		for (int j=0; j<nda; ++j) {
			int t= a[j]*m + c;	
			p[j+i]= t%10;
			c= t/10;
		}
		p[nda+i]= c;
		r= r + p;	
	}
	return r;
}






int main(int argc, char *argv[])
{
	Numero fac("1");
	Numero k("1");
	Numero u("1");
	for (int i=0; i<1000; ++i) {
		fac= fac*k;
		k=k+u;
	}
	std::cout << " 1000! = " << fac << std::endl;
	std::cout << "numero de digitos: " << fac.ndig() << std::endl;
	return EXIT_SUCCESS;
}




