www.pudn.com > vlong.rar > vlong.cpp


/* -------------- constructor start ----------------*/ 
// default constructor, which demand user to input the num 
// need to catch input error exception 
vlong::vlong() 
{ 
	try 
	{ 
		input(); 
		str_to_vec(); 
	} 
	catch(domain_error) // if input is error, set vlong num to zero 
	{ 
		cout << "INPUT ERROR!!!\n"; 
		cout << "num reset to ZERO\n"; 
		num_str = "0"; 
		str_to_vec(); 
	} 
} 
 
// constructor that takes another vlong type as parameter to copy constructor 
// no mistake here if init num is a vlong num already 
vlong::vlong(const vlong& in) : is_positive (in.is_positive), num_str (in.num_str) 
{	str_to_vec();	} 
 
// constructor that takes string type as parameter to copy constructor 
// need to catch input error exception 
vlong::vlong(const string& in)  
{ 
	try 
	{ 
		num_str = in; 
		is_positive = check_positive(num_str);	 
		check_input(); // check if there is no-digit num in string, if so, throw error 
		str_to_vec(); 
	} 
	catch(domain_error) // if input is error, set vlong num to zero 
	{ 
		cout << "INPUT ERROR!!!\n"; 
		cout << "num reset to ZERO\n"; 
		num_str = "0"; 
		str_to_vec();		 
	} 
} 
 
// constructor that takes int type as parameter to copy constructor 
// no mistake here if init num is a int type already 
vlong::vlong(const int& in) 
{ 
	is_positive = (in >= 0 ? true : false); 
 
	// using fstream to transform int into string 
	stringstream tran; 
	tran << in; 
	tran >>	num_str; 
	 
	str_to_vec(); 
} 
 
// constructor that takes classical c char* string type as parameter to copy constructor 
// need to catch input error exception 
vlong::vlong(const char* in) 
{ 
	try 
	{ 
		string t(in); 
		is_positive = check_positive(t); 
		num_str = t; 
		check_input(); // check if there is no-digit num in string, if so, throw error 
		str_to_vec(); 
	} 
	catch(domain_error) // if input is error, set vlong num to zero 
	{ 
		cout << "INPUT ERROR!!!\n"; 
		cout << "num reset to ZERO\n"; 
		num_str = "0"; 
		str_to_vec(); 
	} 
} 
 
// constructor that takes std::vector type as parameter to copy constructor 
vlong::vlong(const vector& in, bool sig = true) 
{ 
	is_positive = sig; 
	num_vector = in; 
	 
	// clear the 0-start element so diminish the size of the vector 
	while (!*num_vector.begin() && num_vector.size() > 1) 
		num_vector.erase(num_vector.begin()); 
	vec_to_str(); 
} 
/* -------------- constructor end ----------------*/ 
 
 
/* -------------- copy pass value overload start----------------*/ 
vlong& vlong::operator=(const vlong& v) 
{ 
	num_str = v.num_str; 
	is_positive = v.is_positive; 
	str_to_vec(); 
	return *this; 
} 
 
vlong& vlong::operator=(const string& v) 
{ 
	num_str = v; 
	is_positive = check_positive(num_str); 
	try 
	{	 
		check_input(); 
		str_to_vec(); 
	} 
	catch (domain_error) 
	{ 
		cout << "INPUT ERROR!!!\n"; 
		cout << "num reset to ZERO\n"; 
		num_str = "0"; 
		str_to_vec(); 
	} 
 
	return *this; 
} 
 
vlong& vlong::operator=(const int& v) 
{ 
	is_positive = (v >= 0 ? true : false);	 
	stringstream tran; 
	tran << v; 
	tran >>	num_str; 
	str_to_vec(); 
	return *this; 
} 
 
vlong& vlong::operator=(const char* v) 
{ 
	string t(v); 
	is_positive = check_positive(t);	 
	num_str = t; 
	try 
	{ 
		check_input(); 
		str_to_vec(); 
	} 
	catch(domain_error) 
	{ 
		cout << "INPUT ERROR!!!\n"; 
		cout << "num reset to ZERO\n"; 
		num_str = "0"; 
		str_to_vec(); 
	} 
 
	return *this;		 
} 
 
vlong& vlong::operator=(const vector& v) 
{ 
	is_positive = true; 
	num_vector = v; 
	vec_to_str(); 
	return *this;	 
} 
/* -------------- copy pass value overload ----------------*/ 
 
 
/* -------------- comparision overload ----------------*/ 
bool operator==(const vlong& l, const vlong& v) 
{	return (l.get_str() == v.get_str() && l.get_sig() == v.get_sig());	} 
 
bool operator!=(const vlong& l, const vlong& v) 
{	return !(l == v);	} 
 
bool operator>(const vlong& l, const vlong& r) 
{ 
	bool tag; 
	if (l.get_sig() && !r.get_sig()) 
		return true; 
	if (!l.get_sig() && r.get_sig()) 
		return false; 
 
	if (l.length() > r.length()) 
			tag = true; 
	else 
		if (l.length() < r.length()) 
			tag = false; 
		else 
			tag = l.get_str() > r.get_str(); 
	if (l.get_sig()) 
		return tag; 
	return !tag; 
} 
 
bool operator>=(const vlong& l, const vlong& r) 
{	return (l == r || l > r);	} 
 
bool operator<(const vlong& l, const vlong& r) 
{	return !(l >= r);	} 
 
bool operator<=(const vlong& l, const vlong& r) 
{	return !(l > r);	} 
/* -------------- comparision overload ----------------*/ 
 
 
/* -------------- arithmetic overload ----------------*/ 
const vlong operator+(const vlong& l, const vlong& r) 
{ 
	vector shorter = l.length() <= r.length() ? l.get_vec() : r.get_vec(); 
	vector longer = l.length() > r.length() ? l.get_vec() : r.get_vec(); 
	 
	if (!l.get_sig() && r.get_sig()) 
		return r - -l; 
	if (l.get_sig() && !r.get_sig()) 
		return l - -r; 
	 
	int cp = 0; 
	 
	vector result(longer.size() + 1); 
 
	vector::iterator i = shorter.end() - 1; 
	vector::iterator j = longer.end() - 1; 
	vector::iterator k = result.end() - 1; 
 
	for (vector::size_type counter = 0; counter < shorter.size(); ++counter) 
	{ 
		*k = *i-- + *j-- + cp; 
		cp = *k-- / seg_num; 
		cp ? *(k + 1) %= seg_num : 0; 
	} 
 
	if (cp != 0 && longer.size() == shorter.size()) 
		*k = 1; 
	else if (longer.size() > shorter.size()) 
		*k-- = *j-- + cp; 
 
	if (*(k + 1) / seg_num) 
	{ 
		*(k + 1) %= seg_num; 
		++(*k); 
	}		 
 
	for (vector::size_type counter = shorter.size(); counter < longer.size() - 1; ++counter) 
		*k-- = *j--;  
 
	vlong rst(result, l.get_sig()); 
	return rst; 
} 
 
const vlong operator-(const vlong& v)  
{ 
	vlong t(v); 
	t.set_sig(!t.get_sig()); 
	return t; 
} 
 
 
const vlong operator-(const vlong& l, const vlong& r) 
{ 
	if (!(l.get_sig() == r.get_sig())) 
		return  l + -r; 
 
	bool sign = (l >= r); 
 
	if (l == r) 
	{ 
		vlong r(0); 
		return r; 
	} 
 
	vector shorter = l < r ? l.get_vec() : r.get_vec(); 
	vector longer = l < r ? r.get_vec() : l.get_vec(); 
	vector result(longer.size() + 1);	 
	 
	int cp = 0; 
	 
 
	vector::iterator i = shorter.end() - 1; 
	vector::iterator j = longer.end() - 1; 
	vector::iterator k = result.end() - 1; 
 
	for (vector::size_type counter = 0 ; counter < shorter.size(); ++counter) 
	{ 
		*k = *j-- - *i-- - cp; 
		if (*k < 0) 
		{ 
			cp = 1; 
			*k += seg_num; 
		} 
		else 
			cp = 0; 
		--k; 
	} 
	 
	if (longer.size() > shorter.size()) 
		*k-- = *j-- - cp; 
 
	for (vector::size_type counter = shorter.size() + 1; counter < longer.size(); ++counter) 
		*k-- = *j--; 
 
	vlong rst(result, sign); 
	return rst; 
} 
 
const vlong operator*(const vlong& l, const vlong& r) 
{ 
	vector result((l.length() + r.length()) / seg_length + 1 ); 
	 
	bool sign = (l.get_sig() == r.get_sig()); 
 
	vector shorter = l.length() <= r.length() ? l.get_vec() : r.get_vec(); 
	vector longer = l.length() > r.length() ? l.get_vec() : r.get_vec(); 
	 
	int cp = 0; 
	 
	vector::iterator i = shorter.end() - 1; 
	vector::iterator j = longer.end() - 1; 
	vector::iterator k = result.end() - 1; 
	 
	// use to extend multiply result 
	long low = 0; 
	long high = 0; 
	 
	for (vector::size_type m = 0 ; m < shorter.size(); ++m) 
	{ 
		for (vector::size_type n = 0; n < longer.size(); ++n) 
		{ 
			low = (*i % divide) * (*j % divide); 
			low += (*i / divide) * (*j % divide) % divide * divide; 
			low += (*i % divide) * (*j / divide) % divide * divide; 
			high = low / seg_num; // to high extend 
			low %= seg_num; 
			high += (*i / divide) * (*j % divide) / divide; 
			high += (*i % divide) * (*j / divide) / divide; 
			high += (*i / divide) * (*j / divide); 
 
			*k += low; 
			cp = *k / seg_num; 
			*k-- %= seg_num; 
			*k += high + cp; 
			low = high = 0; 
			--j; 
		} 
		k += longer.size(); 
		j += longer.size(); 
		--i; 
		--k; 
	} 
 
	vlong rst(result, sign); 
	return rst; 
} 
 
const vlong operator/(const vlong& lhs, const vlong& rhs) 
{ 
	bool sign = (lhs.get_sig() == rhs.get_sig()); 
	string origin = lhs.get_str(); 
	string rst; 
	int div_dig = 0; 
	stringstream transfer; 
	 
	 
	if (rhs == 0) 
		throw domain_error("divide by zero"); 
	 
	if (lhs < rhs) 
		return *new vlong(0); 
	 
	vlong source = origin.substr(0, rhs.length() < origin.size() ? rhs.length() : origin.size()); 
	origin = origin.substr(source.length(), origin.size() - source.length()); 
	 
	string tmp; 
	while (origin.size() || source >= rhs) 
	{ 
		while (source >= rhs) 
		{  
			source-=rhs; 
			++div_dig; 
		} 
		if (div_dig) 
		{ 
			transfer.clear(); 
			transfer << div_dig; 
			transfer >> tmp; 
			rst = rst + tmp ; 
			div_dig = 0; 
		} 
		 
		if (origin.size()) 
		{ 
			tmp = source.get_str() + origin.substr(0, 1); 
			source = tmp; 
			origin.erase(origin.begin()); 
		} 
	} 
	 
	vlong r(rst); 
	r.set_sig(sign); 
	 
	return r; 
} 
 
const vlong operator%(const vlong& lhs, const vlong& rhs) 
{ 
	string origin = lhs.get_str(); 
	string rst; 
	stringstream transfer; 
	 
	 
	if (rhs == 0) 
		throw domain_error("divide by zero"); 
	 
	if (lhs < rhs) 
		return *new vlong(lhs); 
	 
	vlong source = origin.substr(0, rhs.length() < origin.size() ? rhs.length() : origin.size()); 
	origin = origin.substr(source.length(), origin.size() - source.length()); 
	 
	string tmp; 
	while (origin.size() || source >= rhs) 
	{ 
		while (source >= rhs) 
			source-=rhs; 
		 
		if (origin.size()) 
		{ 
			tmp = source.get_str() + origin.substr(0, 1); 
			source = tmp; 
			origin.erase(origin.begin()); 
		} 
	} 
	 
	vlong r(source); 
 
	return r; 
 
} 
 
const vlong operator+(const vlong& lhs, const int rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l + r; 
} 
const vlong operator-(const vlong& lhs, const int rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l - r; 
} 
const vlong operator*(const vlong& lhs, const int rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l * r; 
} 
const vlong operator/(const vlong& lhs, const int rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l / r; 
} 
const vlong operator%(const vlong& lhs, const int rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l % r; 
} 
 
const vlong operator+(const vlong& lhs, const string& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l + r; 
} 
const vlong operator-(const vlong& lhs, const string& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l - r; 
} 
const vlong operator*(const vlong& lhs, const string& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l * r; 
} 
const vlong operator/(const vlong& lhs, const string& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l / r; 
} 
const vlong operator%(const vlong& lhs, const string& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l % r; 
} 
 
const vlong operator+(const int lhs, const vlong& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l + r; 
} 
const vlong operator-(const int lhs, const vlong& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l - r; 
} 
const vlong operator*(const int lhs, const vlong& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l * r; 
} 
const vlong operator/(const int lhs, const vlong& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l / r; 
} 
const vlong operator%(const int lhs, const vlong& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l % r; 
} 
 
const vlong operator+(const string& lhs, const vlong& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l + r; 
} 
const vlong operator-(const string& lhs, const vlong& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l - r; 
} 
const vlong operator*(const string& lhs, const vlong& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l * r; 
} 
const vlong operator/(const string& lhs, const vlong& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l / r; 
} 
const vlong operator%(const string& lhs, const vlong& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l % r; 
} 
 
const vlong operator+(const int lhs, const string& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l + r; 
} 
const vlong operator-(const int lhs, const string& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l - r; 
} 
const vlong operator*(const int lhs, const string& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l * r; 
} 
const vlong operator/(const int lhs, const string& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l / r; 
} 
const vlong operator%(const int lhs, const string& rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l % r; 
} 
 
 
const vlong operator+(const string& lhs, const int rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l + r; 
} 
const vlong operator-(const string& lhs, const int rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l - r; 
} 
const vlong operator*(const string& lhs, const int rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l * r; 
} 
const vlong operator/(const string& lhs, const int rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l / r; 
} 
const vlong operator%(const string& lhs, const int rhs) 
{ 
	vlong l(lhs); 
	vlong r(rhs); 
	return l % r; 
} 
 
 
vlong& vlong::operator++() 
{	return *this = *this + 1;	} 
 
vlong& vlong::operator--() 
{	return *this = *this - 1;	} 
 
const vlong operator+=(vlong& lhs, const vlong& rhs) 
{	return lhs = lhs + rhs;	} 
const vlong operator+=(vlong& lhs, const int rhs) 
{	return lhs = lhs + rhs;	} 
const vlong operator+=(vlong& lhs, const string& rhs) 
{	return lhs = lhs + rhs;	} 
 
const vlong operator-=(vlong& lhs, const vlong& rhs) 
{	return lhs = lhs - rhs;	} 
const vlong operator-=(vlong& lhs, const int rhs) 
{	return lhs = lhs - rhs;	} 
const vlong operator-=(vlong& lhs, const string& rhs) 
{	return lhs = lhs - rhs;	} 
 
const vlong operator*=(vlong& lhs, const vlong& rhs) 
{	return lhs = lhs * rhs;	} 
const vlong operator*=(vlong& lhs, const int rhs) 
{	return lhs = lhs * rhs;	} 
const vlong operator*=(vlong& lhs, const string& rhs) 
{	return lhs = lhs * rhs;	} 
 
const vlong operator/=(vlong& lhs, const vlong& rhs) 
{	return lhs = lhs / rhs;	} 
const vlong operator/=(vlong& lhs, const int rhs) 
{	return lhs = lhs / rhs;	} 
const vlong operator/=(vlong& lhs, const string& rhs) 
{	return lhs = lhs / rhs;	} 
 
const vlong operator%=(vlong& lhs, const vlong& rhs) 
{	return lhs = lhs % rhs;} 
const vlong operator%=(vlong& lhs, const int rhs) 
{	return lhs = lhs % rhs;} 
const vlong operator%=(vlong& lhs, const string& rhs) 
{	return lhs = lhs % rhs;} 
/* -------------- arithmetic overload ----------------*/ 
 
 
/* -------------- stream overload ----------------*/ 
ostream& operator<<(ostream& os, const vlong& v) 
{	os << v.get_str();	} 
 
istream& operator>>(istream& is, vlong& v) 
{	 
	string s; 
	is >> s; 
	v = s; 
} 
/* -------------- stream overload ----------------*/ 
 
 
 
// Propety function 
void vlong::input() 
{ 
	cout << "Please input the very long num: "; 
	cin >> num_str; 
	is_positive = check_positive(num_str);	 
	check_input(); 
} 
 
const string vlong::get_str() const 
{	return num_str;	} 
	 
void vlong::output() const 
{	 
	if (!is_positive) cout << '-'; 
	cout << num_str << endl; 
} 
 
void vlong::output_num_vector() const 
{	 
	for (vector::const_iterator i = num_vector.begin(); i != num_vector.end(); ++i) 
		cout << *i << " "; 
	cout << endl;	 
} 
 
const bool vlong::get_sig() const 
{	return is_positive;	} 
 
void vlong::set_sig(bool b) 
{	is_positive = b;	} 
 
const int vlong::length() const 
{	return num_str.size();	} 
 
const vector vlong::get_vec() const 
{	return num_vector;	} 
 
 
const vlong abs(const vlong& v) 
{ 
	vlong r(v); 
	r.set_sig(true); 
	return r; 
} 
 
 
 
 
// check function 
void vlong::check_input() 
{ 
	for (string::iterator i = num_str.begin(); i != num_str.end() ; ++i) 
		if (*i < '0' || *i > '9') 
			throw domain_error("INPUT WRONG!!!"); 
	while(*num_str.begin() == '0') 
		num_str.erase(num_str.begin()++); 
} 
 
bool vlong::check_positive(string& s) 
{ 
	string::iterator i = s.begin(); 
	if (*i == '-') 
	{ 
		s.erase(i); 
		return false; 
	} 
	return true;	 
} 
 
 
 
 
 
// turned the vector to string, every element in vector is 8-digital decimal 
void vlong::vec_to_str() 
{ 
	string str; 
	num_str = ""; 
	stringstream tran;	 
 
	for (vector::size_type i = 0; i < num_vector.size(); ++i) 
	{ 
 
		tran << num_vector[i]; 
		tran >> str; 
		if (!(str == "0" && num_vector.size() > 1)) 
			num_str += str; 
		tran.clear(); 
	} 
} 
 
// turned the string to vector, every element in vector is 8-digital decimal 
void vlong::str_to_vec() 
{ 
	long power; 
	 
	if (num_str == "") 
	{ 
		vector new_vec; 
		new_vec.push_back(0); 
		num_vector = new_vec; 
		return; 
	}		 
 
	for (vector::size_type i = num_vector.size(); i <= (num_str.size() - 1) / seg_length; ++i) 
		num_vector.push_back(0); 
 
	for (vector::size_type i = 0; i < num_vector.size(); ++i) 
		num_vector[i] =0; 
 
	string::iterator i = num_str.end() - 1; 
 
	for (vector::size_type counter = num_vector.size(); counter > 0; --counter) 
	{ 
		power = 1; 
		 
		for (int j = 0; j < seg_length; ++j) 
		{ 
			if (i + 1 != num_str.begin()) 
				num_vector[counter - 1] += power * (*i-- - '0'); 
			else 
				j = seg_length; 
			power *= 10; 
		} 
	} 
}