头文件BigData.h:
#ifndef BIG_DATA_H
#define BIG_DATA_H
#include<string>
#define MAX_INT64 0x7FFFFFFFFFFFFFFF
#define MIN_INT64 0x8000000000000000
#define UN_INIT 0xCCCCCCCCCCCCCCCC
typedef long long INT64;
class BigData
{
public:
BigData( INT64 value = 0xCCCCCCCCCCCCCCCC);
BigData( const char * pData);
BigData operator+(const BigData& bigdata); //传值方式
BigData operator-(const BigData& bigdata);
BigData operator*(const BigData& bigdata);
BigData operator/(const BigData& bigdata);
private:
bool IsINT64OverFlow()const ;
void INT64ToString();
bool IsLeftStrBig(const char* pLeft, int LSize, const char* pRight, int RSize);
char SubLoop(char * pLeft, int LSize, const char * pRight, int RSize);
friend std::ostream & operator<<(std::ostream& _cout, const BigData& bigdata);
std:: string Add(std::string left, std::string right);
std:: string Sub(std::string left, std::string right);
std:: string Mul(std::string left, std::string right);
std:: string Div(std::string left, std::string right);
private:
INT64 _value;
std:: string _strData;
};
#endif
源文件BigData.cpp:
#define _CRT_SECURE_NO_WARNINGS 1
#include "BigData.h"
#include <assert.h>
#include<string>
//构造函数
BigData::BigData(INT64 value)
:_value(value)
{
INT64ToString();
}
//拷贝构造函数
BigData::BigData(const char* pData)
{
//参数检测
if (NULL == pData)
{
assert(false );
return;
}
char cSombol = pData [0];
char *pStr = (char *)pData;
//检查符号,"+","-"
if ('+' == cSombol || '-' == cSombol)
{
pStr++;
}
//检查第一位字符位
else if (cSombol >= '0'&&cSombol <= '9')
{
cSombol = '+';
}
//处理全为空格,“ ”
else
{
return;
}
//消除0,“000012345”
while (*pStr == '0' )
{
pStr++;
}
_strData.resize(strlen( pData)+1);
_strData[0] = cSombol; //保存符号位
//处理非法字符,“123456qwe”
_value = 0;
int iCount = 1;
while (*pStr >= '0' && *pStr <= '9')
{
//转化步骤
_value = _value * 10 + (*pStr - '0');
_strData[iCount++] = *pStr;
pStr++;
}
_strData.resize(iCount);
//处理负数
if (cSombol == '-' )
{
_value = 0 - _value;
}
}
//大数加法
BigData BigData ::operator+(const BigData& bigdata )
{
//左右操作数都没有溢出,为内置类型
if (IsINT64OverFlow() && bigdata .IsINT64OverFlow())
{
//异号相加,+,-
if (_strData[0] != bigdata ._strData[0])
{
return BigData (_value + bigdata._value);
}
else //同号相加
{
INT64 tmp = MIN_INT64 - _value;
if ((_value >= 0 && MAX_INT64 - _value >= bigdata._value)||
(_value < 0 && tmp/*MIN_INT64 - _value*/ <= bigdata._value))
{
return BigData (_value + bigdata._value);
}
}
}
//至少有一个溢出或结果溢出
if (_strData[0] == bigdata ._strData[0])
{
return BigData (Add(_strData, bigdata._strData).c_str());
}
return BigData (Sub(_strData, bigdata._strData).c_str());
}
//大数减法
BigData BigData ::operator-(const BigData& bigdata )
{
//同号相减
if (IsINT64OverFlow() && bigdata .IsINT64OverFlow())
{
if (_strData[0] == bigdata ._strData[0])
{
return BigData (_value - bigdata._value);
}
else //异号无溢出
{
if ((_value > 0 && MAX_INT64 + bigdata._value >= _value) ||
(_value < 0 && MIN_INT64 + bigdata._value <= _value))
{
return BigData (_value - bigdata._value);
}
}
}
//有溢出
if (_strData[0] != bigdata ._strData[0])//异号
{
return BigData (Add(_strData, bigdata._strData).c_str());
}
return BigData (Sub(_strData, bigdata._strData).c_str());
}
//大数乘法
BigData BigData ::operator*(const BigData& bigdata )
{
//除数不为0
if (_value == 0 || bigdata ._value == 0)
{
return BigData (INT64(0));
}
//没有溢出
if (IsINT64OverFlow() && bigdata .IsINT64OverFlow())
{
//同号
if (_strData[0] == bigdata ._strData[0])
{
if ((_value>0 && MAX_INT64 / _value >= bigdata._value)||
(_value<0 && MIN_INT64 / _value <= bigdata._value))
{
return BigData (_value*bigdata._value);
}
}
//异号
else
{
if ((_value>0 && MAX_INT64 / _value <= bigdata._value) ||
(_value<0 && MIN_INT64 / _value >= bigdata._value))
{
return BigData (_value*bigdata._value);
}
}
}
return BigData (Mul(_strData, bigdata._strData).c_str());
}
//大数除法
BigData BigData ::operator/(const BigData& bigdata )
{
//除数为零
if (bigdata ._strData[1] == '0')
{
assert(false );
}
//都没溢出
if (IsINT64OverFlow() && bigdata .IsINT64OverFlow())
{
return BigData (_value / bigdata._value);
}
//被除数小于除数
if (_strData.size() < bigdata ._strData.size()|| //123 123445
(_strData.size() == bigdata._strData.size()&& //2239 2234
strcmp(_strData.c_str()+1, bigdata._strData.c_str()+1)<0))
{
return BigData (INT64(0));
}
//
if (bigdata ._strData == "+1" || _strData == "-1")
{
std:: string ret = _strData;
if (_strData[0] != bigdata ._strData[0])
{
ret[0] = '-';
}
return BigData (ret.c_str());
}
//数值相等
if (strcmp(_strData.c_str() + 1, bigdata ._strData.c_str() + 1) == 0)
{
std:: string ret = "+1" ;
if (_strData[0] != bigdata ._strData[0])
{
ret[0] = '-';
}
return BigData (ret.c_str());
}
return BigData (Div(_strData, bigdata._strData).c_str());
}
//字符串加法
std::string BigData::Add(std::string left, std:: string right )
{
int iLSize = left .size();
int iRSize = right .size();
if (iLSize < iRSize)
{
std::swap( left, right ); //长的放在左边
std::swap(iLSize, iRSize);
}
std:: string sRet;
sRet.resize(iLSize + 1); //最高位可能有进位
sRet[0] = left[0];
char step = 0; //记录进位
for (int iIdx = 1; iIdx < iLSize; iIdx++)
{
char cRet = left [iLSize - iIdx] - '0' + step;
if (iIdx < iRSize)
{
cRet += ( right[iRSize - iIdx] - '0' );
}
sRet[iLSize - iIdx + 1] = cRet % 10 + '0';
step = cRet / 10;
}
sRet[1] = step + '0'; //最高位的进位
return sRet;
}
//字符串减法
std::string BigData::Sub(std::string left, std:: string right )
{
int iLSize = left .size();
int iRSize = right .size();
char cSymbol = left [0];
if (iLSize < iRSize||
iLSize ==iRSize&&
left < right )
{
std::swap( left, right );
std::swap(iLSize, iRSize);
if (cSymbol == '+' )
{
cSymbol = '-';
}
else
{
cSymbol = '+';
}
}
std:: string strRet; //保存结果
strRet.resize( left.size());
strRet[0] = cSymbol;
//从低往高,取left的每一位
//从低往高,取right的每一位
for (int Idx = 1; Idx < iLSize; Idx++)
{
char cRet = left [iLSize - Idx] - '0';
if (Idx < iRSize)
{
cRet -= ( right[iRSize - Idx] - '0' );
}
//判断是否借位
if (cRet < 0)
{
left[iLSize - Idx - 1] -= 1;
cRet += 10;
}
strRet[iLSize - Idx] = cRet + '0';
}
return strRet;
}
//字符串乘法
std::string BigData::Mul(std::string left, std:: string right )
{
//确定符号位
char cSymbol = '+' ;
if (left [0] != right[0])
{
cSymbol = '-';
}
int iLSize = left .size();
int iRSize = right .size();
if (iLSize > iRSize)
{
std::swap( left, right );
std::swap(iLSize, iRSize);
}
std:: string sRet;
sRet.assign(iLSize + iRSize - 1, '0');
sRet[0] = cSymbol;
int iDataLen = sRet.size();
int ioffset = 0; //记录偏移量
//取左边一位,与右边的每一位相乘
for (int iLIdx = 1; iLIdx < iLSize; ++iLIdx)
{
char cLeft = left [iLSize - iLIdx] - '0';
char cStep = 0;
if (cLeft == 0)
{
ioffset++;
continue;
}
for (int iRIdx = 1; iRIdx < iRSize; ++iRIdx)
{
char cRet = cLeft*(right [iRSize - iRIdx] - '0') + cStep;
cRet += sRet[iDataLen - iRIdx - ioffset] - '0';
sRet[iDataLen - iRIdx - ioffset] = (cRet % 10) + '0';
cStep = cRet / 10;
}
sRet[iDataLen - iRSize - ioffset] += cStep;
ioffset++;
}
return sRet;
}
//字符串除法
std::string BigData::Div(std::string left, std:: string right )
{
std:: string sRet;
//符号位
sRet.append(1, '+');
if (left [0] != right[0])
{
sRet[0] = '-';
}
char* pLeft = (char *)(left.c_str() + 1);
char* pRight = (char *)(right.c_str() + 1);
int LSize = left .size() - 1;
int DataLen = right .size() - 1;
for (int iIdx = 0; iIdx < LSize;)
{
//处理被除数中的0
if (*pLeft == '0' )
{
sRet.append(1, '0');
pLeft++;
iIdx++;
continue;
}
if (!IsLeftStrBig(pLeft, DataLen, pRight, right.size() - 1))
{
sRet.append(1, '0');
DataLen++;
if (DataLen + iIdx > LSize)
{
break;
}
}
else
{
sRet.append(1, SubLoop(pLeft, DataLen, pRight, right.size() - 1));
while (*pLeft == '0' && DataLen > 0)
{
pLeft++;
iIdx++;
DataLen--;
}
DataLen++;
if (DataLen + iIdx > LSize)
{
break;
}
}
}
return sRet;
}
//判断左边的数大于右边的数
bool BigData ::IsLeftStrBig(const char* pLeft , int LSize, const char * pRight, int RSize)
{
if (LSize > RSize ||
LSize == RSize && strcmp(pLeft, pRight) >= 0)
{
return true ;
}
return false ;
}
//循环相减
char BigData ::SubLoop(char* pLeft, int LSize, const char * pRight, int RSize)
{
assert(pLeft != NULL && pRight != NULL );
char cRet = '0' ;
while (true )
{
//左小于右
if (!IsLeftStrBig(pLeft , LSize, pRight, RSize ))
{
break;
}
int LDataLen = LSize - 1;
int RDataLen = RSize - 1;
//处理循环相减
while (LDataLen >= 0 && RDataLen >= 0)
{
char ret = pLeft [LDataLen] - '0';
ret -= pRight[RDataLen] - '0' ;
if (ret < 0)
{
pLeft[LDataLen - 1] -= 1;
ret += 10;
}
pLeft[LDataLen] = ret + '0' ;
LDataLen--;
RDataLen--;
}
//跳过相减产生的多余的0
while (*pLeft == '0' && LSize > 0)
{
pLeft++;
LSize--;
}
cRet++;
}
return cRet;
}
//检查是否溢出
bool BigData ::IsINT64OverFlow() const
{
//+9223372036854775807
//-9223372036854775808
std:: string tmp("+9223372036854775807" );
if (_strData[0] == '-' )
{
tmp = "-9223372036854775808";
}
if (_strData.size() < tmp.size())
{
return true ;
}
else if ((_strData.size() == tmp.size()) && (_strData <= tmp))
{
return true ;
}
return false ;
}
void BigData ::INT64ToString()
{
//处理符号位
INT64 tmp = _value;
char cSymbol = '+' ;
if (_value < 0)
{
cSymbol = '-';
}
_strData.append(1, cSymbol); //append 追加
//转化
while (tmp)
{
int c = tmp % 10;
if (c < 0)
{
c = 0 - c;
}
_strData.append(1, c + '0');
tmp /= 10;
}
char *pleft = (char *) _strData.c_str() + 1;
char *pright = pleft + _strData.size() - 2;
while (pleft < pright)
{
char cTemp = *pleft;
*pleft++ = *pright;
*pright-- = cTemp;
}
}
//重载输出操作符
std::ostream& operator<<(std:: ostream& _cout , const BigData& bigdata)
{
if (bigdata .IsINT64OverFlow())
{
_cout << bigdata ._value << std::endl;
}
else
{
char* pData = (char *)bigdata._strData.c_str();
if ('+' == pData[0])
{
pData++;
}
_cout << pData << std::endl;
}
return _cout ;
}
测试BigDataTest.cpp:
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include"BigData.h"
void test1() //测试加法
{
//BigData b1(23456);
//BigData b2("23456");
//BigData b3("+23456");
//BigData b4("+23456dfg");
//BigData b5("-23456");
//BigData b6(" ");
//BigData b7("000000023456");
//cout << b1 << endl;
//cout << b2 << endl;
//cout << b3 << endl;
//cout << b4 << endl;
//cout << b5 << endl;
//cout << b6 << endl;
//cout << b7 << endl;
/*BigData left(36789);
BigData right(23761);
cout << left + right << endl;*/
/*BigData left(9223372036854775807);
BigData right(2);
cout << left + right << endl;*/
/*BigData left1("-9223372036854775808");
BigData right1("-3");
cout << left1 + right1 << endl;*/
BigData left("99999999999999999999999999999999" );
BigData right("11111111111111111111111111111111" );
cout << left + right << endl;
}
void test2() //测试减法
{
/*BigData left(56789);
BigData right(25323);
cout << left - right << endl;*/
/*BigData left(9223372036854775807);
BigData right(999);
cout << left - right << endl;*/
/*BigData left("111111111111111111111111111111111111111");
BigData right("99");
cout << left - right << endl;*/
/*BigData left(9223372036854775807);
BigData right(-999);
cout << left - right << endl;*/
/*BigData left("-9223372036854775808");
BigData right("999");
cout << left - right << endl;*/
BigData left("-9223372036854775809" );
BigData right("-999" );
cout << left - right << endl;
}
void test3() //测试乘法
{
/*BigData left("99");
BigData right("999999999999999999999999999999999");
cout << left*right << endl;*/
//BigData left(99999);
//BigData right(99);
//cout << left*right << endl;
/*BigData left("99");
BigData right("-999999999999999999999999999999999");
cout << left*right << endl;*/
BigData left(-99);
BigData right(99999);
cout << left*right << endl;
}
void test4() //测试除法
{
/*BigData left(99999);
BigData right(99999);
cout << left/right << endl;*/
/*BigData left("222222222222222222222222222222");
BigData right("33");
cout << left / right << endl;*/
/*BigData left(-999990000000000);
BigData right(99999);
cout << left / right << endl;*/
BigData left(678789);
BigData right(99999135547);
cout << left / right << endl;
}
int main()
{
//test1();
//test2();
//test3();
test4();
system( "pause");
return 0;
}
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。