大整数加减乘除及取模运算 C++实现

来源:互联网 发布:pb网络用语 编辑:程序博客网 时间:2024/06/05 06:16

最近事情实在是太多了,一直没有时间写博客,昨天刚刚忙完硕士开题,虽然还是有很多的事情要做,

但实在是不想弄了。想起一个月之前就已经写完的一个大整数加减乘除法的程序,今天把它贴出来和大家分享,

目前我只是做了简单的测试,可能程序中还存在不好的bug,也希望大家能一块帮着指出其中的错误!!

希望和大家一块学习共勉 .....

工程下载地址(也可以留下邮箱,我会将工程发过去):http://download.csdn.net/detail/doufei_ccst/6693721

首先是实现大整数的头文件:BitInt.h

#ifndefDOUFEI_BIGINT_HEADER#defineDOUFEI_BIGINT_HEADER#include <string>#include <iostream>class CBigInt{public:explicit CBigInt() ; CBigInt(const int i) ; CBigInt(const std :: string& strValues) ;CBigInt(const CBigInt& bigInt) ; //复制构造函数~CBigInt() ;public:bool inline isPositive() {return flag ; };int compareBitInt(const CBigInt& rhs)const ; //比较两个数的大小CBigInt& operator = (const CBigInt& rhs) ; //赋值操作符重载friend std :: ostream& operator << (std :: ostream& ou, const CBigInt& bigInt) ; //重载输出操作符friend std :: istream& operator >> (std :: istream& in, CBigInt& bigInt) ; //输入操作符的重载friend const CBigInt operator + (const CBigInt& lhs, const CBigInt& rhs ) ; //加法操作重载friend const CBigInt operator - (const CBigInt& lhs, const CBigInt& rhs) ; //减法操作符重载friend const CBigInt operator * (const CBigInt& lhs, const CBigInt& rhs) ; //乘法操作符重载friend const CBigInt operator / (const CBigInt& lhs, const CBigInt& rhs) ; //除法操作重载friend const CBigInt operator % (const CBigInt& lhs, const CBigInt& rhs) ; //取模运算操作符重载void setValue(const std :: string& strValues) ; //根据字符串设置数值const CBigInt absolute()const ; //绝对值private:std :: string values ; //保存所有位上的数字bool flag ; //true表示正数,false表示负数,0默认为正数};std :: ostream& operator << (std :: ostream& ou, const CBigInt& bigInt) ;std :: istream& operator >> (std :: istream& in, CBigInt& bigInt) ;const CBigInt operator + (const CBigInt& lhs, const CBigInt& rhs ) ; //加法操作符重载const CBigInt operator - (const CBigInt& lhs, const CBigInt& rhs) ; //剑法操作符重载const CBigInt operator * (const CBigInt& lhs, const CBigInt& rhs) ; //乘法操作符重载const CBigInt operator / (const CBigInt& lhs, const CBigInt& rhs) ; //除法操作重载const CBigInt operator % (const CBigInt& lhs, const CBigInt& rhs) ; //取模运算操作符重载#endif


BitInt.cpp

#include "BigInt.h"#include <cmath>#include <iostream>#include <string>#include <algorithm>#include <time.h>#include <cassert>using namespace std;CBigInt :: CBigInt() : values(""), flag(true){}CBigInt :: CBigInt(const int i){values.clear() ;if (i >= 0) flag = true ;elseflag = false ;int v = abs(i) ;while(v){values.push_back(char('0' + (v % 10))) ;v /= 10 ;}reverse(values.begin(), values.end()) ;if (values.empty()){values.push_back('0') ;flag = true ;}}CBigInt :: CBigInt(const string& strValues){setValue(strValues) ; //调用成员函数完成}CBigInt :: CBigInt(const CBigInt& bigInt) : values(bigInt.values), flag(bigInt.flag){}CBigInt :: ~CBigInt(){}const CBigInt CBigInt :: absolute() const{CBigInt ret(*this) ;ret.flag = true ;return ret ;}int CBigInt :: compareBitInt(const CBigInt& rhs)const{//异号情况if (flag && !rhs.flag) return 1 ;if (!flag && rhs.flag) return -1 ;//同号情况,先比较绝对值,然后根据符号判断大小int ret = 0 ;if (values.length() > rhs.values.length()) ret = 1 ;elseif (values.length() < rhs.values.length()) ret = -1 ;elseret = values.compare(rhs.values) ;if (flag) return ret ;return -ret ;}void CBigInt :: setValue(const string& strValues){values.clear() ;string tmpStr(strValues.begin() + strValues.find_first_not_of(' '), strValues.end()) ; //去掉前面的空格if (tmpStr.empty()){values.push_back('0') ;flag = true ;return ;}if (tmpStr.at(0) == '-' )flag = false ;elseflag = true ;int i = tmpStr.find_first_of("0123456789") ;int j = tmpStr.find_last_of("0123456789") ;values = tmpStr.substr(i, j - i + 1) ;//从符号位之后开始的所有数字,直到遇到第一个非数字位}CBigInt& CBigInt :: operator = (const CBigInt& rhs){this->values = rhs.values ;this->flag = rhs.flag ;return *this ;}ostream& operator << (ostream& ou, const CBigInt& bigInt){if (!bigInt.flag)ou << '-';ou << bigInt.values ;return ou ;}istream& operator >> (istream& in, CBigInt& bigInt){string str ;in >> str ;bigInt.setValue(str) ; //设置读入的新的数值return in ;}const CBigInt operator + (const CBigInt& lhs, const CBigInt& rhs){CBigInt ret ;if (lhs.flag == rhs.flag) //符号相同{string lvalues(lhs.values) , rvalues(rhs.values) ;reverse(lvalues.begin(), lvalues.end()) ;reverse(rvalues.begin(), rvalues.end()) ;//逐位相加int i = 0;for ( ; i < lvalues.length() && i < rvalues.length(); ++ i)ret.values.push_back(lvalues.at(i) + rvalues.at(i) - '0') ;if (i < lvalues.length())for (; i < lvalues.length(); ++ i)ret.values.push_back(lvalues.at(i)) ;elsefor (; i < rvalues.length(); ++ i)ret.values.push_back(rvalues.at(i)) ;//处理进位int carry = 0;for (int i = 0; i < ret.values.length(); ++ i){int newValue = ret.values.at(i) - '0' + carry ;carry = newValue/ 10 ;ret.values.at(i) = newValue - carry * 10 + '0' ;}if (carry)ret.values.push_back(carry + '0') ;//处理符号ret.flag = lhs.flag ;}else //符号不同{CBigInt absL = lhs.absolute() ;CBigInt absR = rhs.absolute() ;int compFlag = absL.compareBitInt(absR) ;if (compFlag == 0){ret.setValue("0") ;ret.flag = true ;return ret ;}else{if (compFlag == -1) //交换位置,使得absL > absR{CBigInt tmp(absL) ;absL = absR ;absR = tmp ;}reverse(absL.values.begin(), absL.values.end()) ;reverse(absR.values.begin(), absR.values.end()) ;//处理差值int i = 0;for (; i < absL.values.length() && i < absR.values.length(); ++ i)ret.values.push_back(absL.values.at(i) - absR.values.at(i) + '0') ;if (i < absL.values.length()) //不可能出现i < absR.values.length()的情况for (; i < absL.values.length(); ++ i) ret.values.push_back(absL.values.at(i)) ;//处理借位int carry = 0 ;for (i = 0; i < ret.values.length(); ++ i){int newValue = ret.values.at(i) - carry - '0' ;if (newValue < 0) carry = 1 ; //向前借位else carry = 0 ;ret.values.at(i) = newValue + carry * 10 + '0' ;}//处理符号if (compFlag == 1)ret.flag = lhs.flag ;elseret.flag = rhs.flag;}}reverse(ret.values.begin(), ret.values.end()) ;int i = ret.values.find_first_not_of(" 0") ;if (i == string :: npos)//空的,说明结果是0{ret.setValue("0") ;ret.flag = true ;return ret ;}ret.values = string(ret.values.begin() + ret.values.find_first_not_of(" 0"), ret.values.end()) ; //去掉前面的空白和0return ret ;}const CBigInt operator - (const CBigInt& lhs, const CBigInt& rhs){CBigInt tmpRhs(rhs) ;tmpRhs.flag = !tmpRhs.flag ; //取负号return (lhs + tmpRhs) ;}//乘法操作符重载const CBigInt operator * (const CBigInt& lhs, const CBigInt& rhs){CBigInt ret ;int flag1 = lhs.compareBitInt(CBigInt(0)) ;int flag2 = rhs.compareBitInt(CBigInt(0)) ;if (flag1 == 0 || flag2 == 0){ret.setValue("0") ;ret.flag = true ;return ret ;}if (lhs.flag == rhs.flag) ret.flag = true ;//同号为正,异号为负else ret.flag = false ;string lvalues(lhs.values), rvalues(rhs.values) ;reverse(lvalues.begin(), lvalues.end())  ;reverse(rvalues.begin(), rvalues.end()) ;ret.values.resize(lvalues.size() + rvalues.size(), '0') ;//相乘for (int i = 0; i < lvalues.size(); ++ i)for (int j = 0; j < rvalues.size(); ++ j){int newValue = ret.values[i + j] +  (lvalues[i] - '0') * (rvalues[j] - '0') - '0';int carry = newValue / 10 ;ret.values[i + j] = newValue % 10 + '0' ;//这里之所以对每一位进行进位处理,是为了防止出现溢出情况的出现,如'0' + 9 * 9 = 48 + 81 > 127已经溢出for (int k = i + j + 1; carry != 0 && k < ret.values.size(); ++ k) //处理进位{ret.values[ k - 1 ] = newValue % 10 + '0' ;newValue = ret.values[k] + carry - '0';ret.values[k] = newValue % 10 + '0' ;carry = newValue / 10 ;}}reverse(ret.values.begin(), ret.values.end()) ; //翻转ret.values = string(ret.values.begin() + ret.values.find_first_not_of(" 0"), ret.values.end()) ; //去掉前面的空白和0return ret ;}const CBigInt operator / (const CBigInt& lhs, const CBigInt& rhs)  //除法操作重载{CBigInt ret ;assert(rhs.compareBitInt(CBigInt(0)) != 0) ;ret.setValue("0") ; //初始化为0CBigInt absL(lhs.absolute()) ;CBigInt absR(rhs.absolute()) ;int comFlag = absL.compareBitInt(absR) ;if (comFlag < 0)return ret ;if(comFlag == 0){ret.setValue("1") ;if (lhs.flag == rhs.flag) ret.flag = true ;elseret.flag = false ;return ret ;}int movCount = absL.values.size() - absR.values.size() ;const CBigInt tenBigInt(10) ;//使用减法实现除法的操作do {CBigInt tmp(absR) ;for (int i = 0; i < movCount; ++ i) //tmp是10的movCount次方tmp = tmp * tenBigInt ;int addNum = 0 ;while(absL.compareBitInt(tmp) >= 0){absL = absL - tmp ;addNum ++ ;}ret = ret * tenBigInt + CBigInt (addNum) ;movCount -- ;}while (movCount >= 0);if (lhs.flag == rhs.flag) ret.flag = true ;elseret.flag = false ;return ret ;}const CBigInt operator % (const CBigInt& lhs, const CBigInt& rhs)  //取模运算操作符重载{CBigInt divTmp = lhs / rhs ;return (lhs - rhs * divTmp) ;}

测试主函数:main.cpp

#include <iostream>#include <fstream>#include "BigInt.h"#include <string>using namespace std ;int main(int argc, char** argv){ifstream in("data.txt") ;#define  cin in string num1, num2 ;cin >> num1 >> num2 ;CBigInt bi1(num1);CBigInt bi2(num2) ;cout << "第一个操作数是:" << bi1 << endl ;cout << "第二个操作数是:" << bi2 << endl;cout << "乘法结果:" << bi1 * bi2 << endl;cout <<"加法结果:" << (bi1 + bi2) << endl;cout << "减法结果:" <<(bi1 - bi2) << endl;cout << "除法的结果是:" << bi1/bi2 << endl;cout << "取模的结果是:" << bi1 % bi2 << endl;return 0 ;}


测试数据放在一个data.txt文件中,内容是两个操作数,如下:

999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999-999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998999899989998

程序的运行结果是:



工程下载地址(也可以留下邮箱,我会将工程发过去):http://download.csdn.net/detail/doufei_ccst/6693721

希望能够指正程序中的错误和不足,共同学习进步 ....


0 0
原创粉丝点击