// big_integer.h
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class NumberFormatException
{
private:
string str;
public:
NumberFormatException(string);
friend ostream& operator<<(ostream&,const NumberFormatException&);
};
class DividedByZeroException
{
private:
string str;
public:
DividedByZeroException(string);
friend ostream& operator<<(ostream&,const DividedByZeroException&);
};
class big_integer
{
private:
vector<char> digits; //
bool sign; // true for positive, false for negitive
void trim(); // remove zeros in tail, but if the value is 0, keep only one:)
public:
explicit big_integer(long); // construct with a long integer
explicit big_integer(string&)throw(NumberFormatException);
// construct with a string, which must be all integers-bits
// a sign can also be included. if the format is wrong, this will generate an Exception
big_integer(const big_integer&);
big_integer operator=(const big_integer& op2){
digits = op2.digits;
sign = op2.sign;
return (*this);
}
big_integer abs()const{
if( sign ) return *this;
else return -(*this);
}
//binary operators
friend big_integer operator+=(big_integer&,const big_integer&);
friend big_integer operator-=(big_integer&,const big_integer&);
friend big_integer operator*=(big_integer&,const big_integer&);
friend big_integer operator/=(big_integer&,const big_integer&)throw(DividedByZeroException);
friend big_integer operator%=(big_integer&,const big_integer&)throw(DividedByZeroException);
friend big_integer operator+(const big_integer&,const big_integer&);
friend big_integer operator-(const big_integer&,const big_integer&);
friend big_integer operator*(const big_integer&,const big_integer&);
friend big_integer operator/(const big_integer&,const big_integer&)throw(DividedByZeroException);
friend big_integer operator%(const big_integer&,const big_integer&)throw(DividedByZeroException);
//uniary operators
friend big_integer operator-(const big_integer&); //negative
friend big_integer operator++(big_integer&); //++v
friend big_integer operator++(big_integer&,int); //v++
friend big_integer operator--(big_integer&); //--v
friend big_integer operator--(big_integer&,int); //v--
friend bool operator>(const big_integer&,const big_integer&);
friend bool operator<(const big_integer&,const big_integer&);
friend bool operator==(const big_integer&,const big_integer&);
friend bool operator!=(const big_integer&,const big_integer&);
friend bool operator>=(const big_integer&,const big_integer&);
friend bool operator<=(const big_integer&,const big_integer&);
friend ostream& operator<<(ostream&,const big_integer&); //print the big_integer
};
const big_integer ZERO(0);
const big_integer ONE(1);
// big_integer.cpp
#include <list>
#include <deque>
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include "big_integer.h"
using namespace std;
NumberFormatException::NumberFormatException(string s):str(s){}
ostream& operator<<(ostream& stream,const NumberFormatException& exception){
stream << exception.str;
return stream;
}
DividedByZeroException::DividedByZeroException(string s):str(s){}
ostream& operator<<(ostream& stream,const DividedByZeroException& exception){
stream << exception.str;
return stream;
}
big_integer::big_integer(long val){// construct with a long integer
if (val >= 0){
sign = true;
}else{
sign = false;
val *= (-1);
}
do{
digits.push_back( (char)(val%10) );
val /= 10;
}while ( val != 0 );
trim();
}
void big_integer::trim(){
vector<char>::reverse_iterator iter = digits.rbegin();
while(iter != digits.rend() && (*iter) == '\0'){
digits.pop_back();
iter++;
}
if( digits.size()==0 ){
sign = true;
digits.push_back('\0');
}
}
// construct with a string, which must be all integers-bits
// a sign can also be included. if the format is wrong, this will generate an Exception
big_integer::big_integer(string& def)throw(NumberFormatException){
for ( string::reverse_iterator iter = def.rbegin() ; iter < def.rend(); iter++){
char ch = (*iter);
if (iter == def.rend()-1){
if ( ch == '+' ){
sign = true;
continue;
}
else if(ch == '-' ){
sign = false;
continue;
}
}
if (ch <'0' || ch >'9'){
throw NumberFormatException(string("整数格式不对哦"));
}
digits.push_back( (char)((*iter) - '0' ) );
}
if( digits.empty() ){
throw NumberFormatException(string("整数格式不对哦"));
}
trim();
}
big_integer::big_integer(const big_integer& op2):digits(op2.digits){
sign = op2.sign;
}
//binary operators
big_integer operator+=(big_integer& op1,const big_integer& op2){
if( !!op1.sign == !!op2.sign ){ //只处理相同的符号的情况,异号的情况给-处理
vector<char>::iterator iter1;
vector<char>::const_iterator iter2;
iter1 = op1.digits.begin();
iter2 = op2.digits.begin();
char to_add = 0; //进位
while ( iter1 != op1.digits.end() && iter2 != op2.digits.end()){
(*iter1) = (*iter1) + (*iter2) + to_add;
to_add = (*iter1) / 10;
(*iter1) = (*iter1) % 10;
iter1++;iter2++;
}
while ( iter1 != op1.digits.end() ){
(*iter1) = (*iter1) + to_add;
to_add = (*iter1) / 10;
(*iter1) %= 10;
iter1++;
}
while ( iter2 != op2.digits.end() ){
char val = (*iter2) + to_add;
to_add = val / 10;
val %= 10;
op1.digits.push_back(val);
iter2++;
}
if( to_add != 0 ){
op1.digits.push_back(to_add);
}
return op1;
}else{
if (op1 > ZERO){
return op1 -= (-op2);
}else{
return op1 = (op2 - (-op1) );
}
}
}
big_integer operator-=(big_integer& op1,const big_integer& op2){
if (op2 < ZERO ) return op1 += (-op2);
if( op1 < op2 ) return op1 = -(op2-op1);
if( !!op1.sign == !!op2.sign ){ //只处理相同的符号的情况,异号的情况给+处理
vector<char>::iterator iter1;
vector<char>::const_iterator iter2;
iter1 = op1.digits.begin();
iter2 = op2.digits.begin();
char to_substract = 0; //借位
while ( iter1 != op1.digits.end() && iter2 != op2.digits.end()){
(*iter1) = (*iter1) - (*iter2) - to_substract;
to_substract = 0;
while( (*iter1) < 0 ){
to_substract++;
(*iter1) += 10;
}
iter1++;iter2++;
}
while ( iter1 != op1.digits.end() ){
(*iter1) = (*iter1) - to_substract;
to_substract = 0;
while( (*iter1) < 0 ){
to_substract++;
(*iter1) += 10;
}
iter1++;
}
op1.trim();
return op1;
}else{
if (op1 > ZERO){
return op1 += (-op2);
}else{
return op1 = -(op2 + (-op1));
}
}
}
big_integer operator*=(big_integer& op1,const big_integer& op2){
big_integer result(0);
if (op1 == ZERO || op2==ZERO){
result = ZERO;
}else{
vector<char>::const_iterator iter2 = op2.digits.begin();
while( iter2 != op2.digits.end() ){
if(*iter2 != 0){
deque<char> temp(op1.digits.begin() , op1.digits.end());
char to_add = 0;
deque<char>::iterator iter1 = temp.begin();
while( iter1 != temp.end() ){
(*iter1) *= (*iter2);
(*iter1) += to_add;
to_add = (*iter1) / 10;
(*iter1) %= 10;
iter1++;
}
if( to_add != 0)
temp.push_back( to_add );
int num_of_zeros = iter2 - op2.digits.begin();
while( num_of_zeros != 0 ){
temp.push_front('\0');
num_of_zeros--;
}
big_integer temp2(0);
temp2.digits.pop_back();
temp2.digits.insert( temp2.digits.end() , temp.begin() , temp.end() );
temp2.trim();
result = result + temp2;
}
iter2++;
}
result.sign = ( (op1.sign && op2.sign) || (!op1.sign && !op2.sign) );
}
op1 = result;
return op1;
}
big_integer operator/=(big_integer& op1 , const big_integer& op2 )throw(DividedByZeroException){
if( op2 == ZERO ){
throw DividedByZeroException("除数遇到0");
}
big_integer t1 = op1.abs(),t2 = op2.abs();
if ( t1 < t2 ){
op1 = ZERO;
return op1;
}
//现在 t1 > t2 > 0
//只需将 t1/t2的结果交给result就可以了
deque<char> temp;
vector<char>::reverse_iterator iter = t1.digits.rbegin();
big_integer temp2(0);
while( iter != t1.digits.rend() ){
temp2 = temp2 * big_integer( 10 ) + big_integer( (int)(*iter) );
char s = '\0';
while( temp2 >= t2 ){
temp2 = temp2 - t2;
s = s + 1;
}
temp.push_front( s );
iter++;
}
op1.digits.clear();
op1.digits.insert( op1.digits.end() , temp.begin() , temp.end() );
op1.trim();
op1.sign = ( (op1.sign && op2.sign) || (!op1.sign && !op2.sign) );
return op1;
}
big_integer operator%=(big_integer& op1,const big_integer& op2)throw(DividedByZeroException){
return op1 -= ((op1 / op2)*op2);
}
big_integer operator+(const big_integer& op1,const big_integer& op2){
big_integer temp(op1);
temp += op2;
return temp;
}
big_integer operator-(const big_integer& op1,const big_integer& op2){
big_integer temp(op1);
temp -= op2;
return temp;
}
big_integer operator*(const big_integer& op1,const big_integer& op2){
big_integer temp(op1);
temp *= op2;
return temp;
}
big_integer operator/(const big_integer& op1,const big_integer& op2)throw(DividedByZeroException){
big_integer temp(op1);
temp /= op2;
return temp;
}
big_integer operator%(const big_integer& op1,const big_integer& op2)throw(DividedByZeroException){
big_integer temp(op1);
temp %= op2;
return temp;
}
//uniary operators
big_integer operator-(const big_integer& op){ //negative
big_integer temp = big_integer(op);
temp.sign = !temp.sign;
return temp;
}
big_integer operator++(big_integer& op){ //++v
op += ONE;
return op;
}
big_integer operator++(big_integer& op,int x){ //v++
big_integer temp(op);
++op;
return temp;
}
big_integer operator--(big_integer& op){ //--v
op -= - ONE;
return op;
}
big_integer operator--(big_integer& op,int x){ //v--
big_integer temp(op);
--op;
return temp;
}
bool operator<(const big_integer& op1,const big_integer& op2){
if( !!op1.sign != !!op2.sign )
return !op1.sign && op2.sign;
else{
if(op1.digits.size() != op2.digits.size())
return (op1.sign && op1.digits.size()<op2.digits.size()) || (!op1.sign && op1.digits.size()>op2.digits.size());
//两个的长度也一样了
vector<char>::const_reverse_iterator iter1,iter2;
iter1 = op1.digits.rbegin();iter2 = op2.digits.rbegin();
while( iter1 != op1.digits.rend() ){
if( op1.sign && *iter1 < *iter2 ) return true;
if( !op1.sign && *iter1 > *iter2 ) return true;
iter1++;iter2++;
}
return false;
}
}
bool operator==(const big_integer& op1,const big_integer& op2){
if( !!op1.sign != !!op2.sign || op1.digits.size() != op2.digits.size() ){
return false;
}
vector<char>::const_iterator iter1,iter2;
iter1 = op1.digits.begin();iter2 = op2.digits.begin();
while( iter1!= op1.digits.end() ){
if( *iter1 != *iter2 ) return false;
iter1++;iter2++;
}
return true;
}
bool operator!=(const big_integer& op1,const big_integer& op2){
return !(op1==op2);
}
bool operator>=(const big_integer& op1,const big_integer& op2){
return (op1>op2) || (op1==op2);
}
bool operator<=(const big_integer& op1,const big_integer& op2){
return (op1<op2) || (op1==op2);
}
bool operator>(const big_integer& op1,const big_integer& op2){
return !(op1<=op2);
}
ostream& operator<<(ostream& stream,const big_integer& val){ //print the big_integer
if (!val.sign){
stream << "-";
}
for ( vector<char>::const_reverse_iterator iter = val.digits.rbegin(); iter != val.digits.rend() ; iter++){
stream << (char)((*iter) + '0');
}
return stream;
}
// test_big_integer.cpp
// 测试程序
#include "big_integer.cpp"
#include <fstream>
#include <iostream>
#include <time>
int main()
{
big_integer b(1);
ofstream out;
big_integer result = ONE;
for( int i = 1 ; i <= 6 ; i++){
result *= big_integer(i);
}
cout << "6 != \n" << result<<endl;
return 0;
}