您的位置:首页 > 编程语言 > C语言/C++

【C++】大数的+-*/四则运算

2014-04-07 16:50 387 查看
所谓大数,则指数值特别大的数,可能会有99位,100位,远远超过了long long表示的范围。

这样的数作四则运算,需要用到字符串。用字符串通过每一位的字符的四则运算来模拟。

废话少说,上代码:

#include <iostream>
#include <vector>
using namespace std;

class BigNum{
vector<char> m_vec;
//构造函数,析构函数,size()函数,友元重载>>,<<,重载[] + - * / =。
public:
BigNum();
~BigNum();

public:
int size() const {
return m_vec.size();
}
void clr(){
m_vec.clear();
}

public:
friend ostream& operator<<(ostream &os,const BigNum &data);
friend istream& operator>>(istream &is,BigNum &data);

public:
char operator[](int nIndex) const;

BigNum operator+(const BigNum &data);
BigNum operator-(BigNum &data);
BigNum operator*(const BigNum &data);
BigNum operator/(BigNum &data);
BigNum& operator=(const BigNum &data);
bool operator==(const BigNum &data);
bool operator>(const BigNum &data);
bool operator>=(const BigNum &data);
};

BigNum::BigNum(){}

BigNum::~BigNum(){}

ostream& operator<<(ostream &os,const BigNum &data){
vector<char>::const_iterator itVec = data.m_vec.begin();
for(; itVec != data.m_vec.end(); itVec++){
os << *itVec;
}
os << endl;
return os;
}

istream& operator>>(istream &is,BigNum &data){
//必须清空is的缓冲区,不然is.get()得到的是上一次回车的\n。并且不能用is.ignore(),因为ignore()会把第一次输入的第一个字符删除掉。
is.sync();
while(true){
char c = is.get();
if(' ' == c || '\r' == c || '\n' == c)
break;
if( c < '0' || c > '9'){
data.m_vec.clear();
cerr << "not accept" << endl;
break;
}
data.m_vec.push_back(c);
}

return is;
}

char BigNum::operator[](int nIndex) const
{
if(nIndex < 0 || nIndex >= m_vec.size())
{
cerr << "error occur in []";
return ' ';
}
return m_vec[nIndex];
}

bool BigNum::operator==(const BigNum &data){
if(m_vec.size() != data.m_vec.size())
return false;
for(int i = 0; i < m_vec.size(); i++){
if(m_vec[i] != data.m_vec[i])
return false;
}
return true;
}

bool BigNum::operator>(const BigNum &data){
int a = m_vec.size();
int b = data.m_vec.size();
if(a > b){
return true;
}
else if(a < b){
return false;
}
else if(a == b)
{
for(int i = 0; i < a; i++){
if(m_vec[i] > data.m_vec[i]){
return true;
}
else if(m_vec[i] < data.m_vec[i]){
return false;
}
}
return false;
}
}

bool BigNum::operator>=(const BigNum &data){
if(*this > data || *this == data)
return true;
return false;
}

BigNum BigNum::operator+ (const BigNum &data){
int nCarry = 0;
BigNum numTemp;
vector<char>& vecTemp = numTemp.m_vec; //必须是引用

int i = data.size() - 1;
int j = m_vec.size() -1;
for(; i >= 0 || j >= 0; i--,j--){
char a = j>=0? m_vec[j] - '0': 0;
char b = i>=0? data[i] - '0' :0;
char c = a + b + nCarry;
nCarry = c / 10;
vecTemp.push_back(c%10 + '0');
}

if(nCarry != 0)
{
vecTemp.push_back(nCarry + '0');
}

//reverse vecTemp
for(i = 0, j = vecTemp.size() - 1; i < j; i++,j--)
{
char cTemp = vecTemp[i];
vecTemp[i] = vecTemp[j];
vecTemp[j] = cTemp;
}
return numTemp;
}

BigNum& BigNum::operator=(const BigNum &data)
{
m_vec.clear();
vector<char>::const_iterator itVec = data.m_vec.begin();
for(; itVec != data.m_vec.end(); itVec++)
{
m_vec.push_back(*itVec);
}
return *this;
}

BigNum BigNum::operator*(const BigNum &data){
int nCarry = 0;
BigNum result;
BigNum numTemp;
vector<char>& vecTemp = numTemp.m_vec;

int i = data.size()-1;
for(; i >= 0; i--){
char a = data[i] - '0';
int j = m_vec.size() - 1;
for(; j >= 0; j--){
char b = m_vec[j] - '0';
char c = b * a + nCarry;
nCarry = c/10;
vecTemp.push_back(c % 10 + '0');
}
if(nCarry != 0){
vecTemp.push_back(nCarry + '0');
nCarry = 0;
}

//reverse vecTemp
int n = 0;
int m = vecTemp.size() - 1;
for(; n < m; n++,m--){
char cTemp = vecTemp
;
vecTemp
= vecTemp[m];
vecTemp[m] = cTemp;
}

for(int t = data.size() - 1; t > i; t--)
{
vecTemp.push_back('0');
}

result = result + numTemp;
vecTemp.clear();
}
return result;
}

BigNum BigNum::operator-(BigNum &data){
//m_vec > data.m_vec
int nCarry = 0;
BigNum numTemp;
vector<char>& vecTemp = numTemp.m_vec;

int i = data.size() - 1;
int j = m_vec.size() -1;
for(; i >= 0 || j >= 0; i--,j--){
char a = j>=0? m_vec[j] - '0': 0;
char b = i>=0? data[i] - '0' :0;
char c = a - nCarry;
if(c < b){
//需要借位
c = c + 10;
nCarry = 1;
vecTemp.push_back( (c-b) + '0');
}
else{
nCarry = 0;
vecTemp.push_back( (c-b) + '0');
}
}

//记录前面产生几个0
int zero = 0;
vector<char>::const_iterator itVec = vecTemp.end()-1;
for(; ; itVec--){
if( *itVec == '0'){
zero++;
}
else
break;
if(itVec == vecTemp.begin())
break;
}

//pop掉0
for(int k = zero; k > 0; k--)
vecTemp.pop_back();

//reverse
for(i = 0, j = vecTemp.size() - 1; i < j; i++,j--)
{
char cTemp = vecTemp[i];
vecTemp[i] = vecTemp[j];
vecTemp[j] = cTemp;
}

return numTemp;
}

BigNum BigNum::operator/(BigNum &data){
//m_vec > data.m_vec
BigNum numTemp;
vector<char>& vecTemp = numTemp.m_vec;
BigNum &numThis = *this;

int lenA = m_vec.size();
int lenB = data.m_vec.size();
for (int i = lenB; i < lenA; i++){
data.m_vec.push_back('0');
}
for(int j = lenB; j <= lenA; j++){
int a = 0;
while(numThis >= data){
numThis = numThis - data;
a++;
}
vecTemp.push_back( a + '0');
data.m_vec.pop_back();
}
return numTemp;
}

int main()
{
BigNum numA;
BigNum numB;
BigNum numC;
char opt;
while(1){
cin >> numA;
cin >> opt;
cin >> numB;

switch(opt){
case '+':
numC = numA + numB;
cout << numC;
break;
case '-':
if(numA == numB){
cout << 0 << endl;
}
else if(numA > numB){
numC = numA - numB;
cout << numC;
}
else{
numC = numB - numA;
cout << '-';
cout << numC;
}
break;
case '*':
numC = numA * numB;
cout << numC;
break;
case '/':
if(numA == numB){
cout << 1 << endl;
}
else if(numA > numB){
numC = numA / numB;
cout << numC;
}
else{
cout << 0 << endl;
}
break;
}
//清空numA,numB。
numA.clr();
numB.clr();
numC.clr();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: