分享
 
 
 

[原创]最近学习STL,在C++库中苦寻不到BigInteger类,于是自己写了一个

王朝c/c++·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

// 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;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有