大資料的運算加減乘除
BigData.h:
#ifndef __BIG_DATA_H__
#define __BIG_DATA_H__
#include <assert.h>
#include <string>
typedef long long INT64;
//#define MININT64 -9223372036854775808 // 編譯器檢查有錯
//
//#define MAXINT64 +9223372036854775807
const INT64 MININT64 = +9223372036854775807 + 1;
const INT64 MAXINT64 = +9223372036854775807;
class BigData
{
friend std::ostream& operator<<(std::ostream& _cout, const BigData& bigData);
public:
BigData(INT64 value = 0xCCCCCCCCCCCCCCCC);
BigData(const char* str);
BigData operator+(const BigData& bigData);
BigData operator-(const BigData& bigData);
BigData operator*(const BigData& bigdata);
BigData operator/(const BigData& bigdata);
protected:
void _Int64ToStr();
bool _IsINT64OverFlow()const;
std::string AddStr(const BigData& bigData)const;
std::string SubStr(const BigData& bigData)const;
std::string MulStr(const BigData& bigData)const;
std::string DivStr(const BigData& bigData)const;
bool IsLeftStrBig(const char* pLeft, int iLSize, const char* pRight, int iRSize)const;
char LoopSub(char* pLeft, int iLSize, const char* pRight, int iRSize)const;
private:
INT64 _value;
std::string _pData;
};
std::ostream& operator<<(std::ostream& _cout, const BigData& bigData);
#endif /*__BIG_DATA_H__*/
BigData.cpp:
#define _CRT_SECURE_NO_WARNINGS 1
#include "BigData.h"
BigData::BigData(INT64 value) :_value(value)
{
this->_Int64ToStr();
}
BigData::BigData(const char* str) : _value(0)
{
assert(str);
char* temp = (char*)str;
char cSign = '+';
while (isspace(*temp)) //*temp == ' '不能消除tab
{
++temp;
}
if ((*temp == '-') || (*temp == '+'))
{
cSign = *temp;
++temp;
}
this->_pData.resize(strlen(str) + 1);
this->_pData[0] = cSign;
int iCount = 1;
while (*temp == '0')//處理000123
{
++temp;
}
while ((*temp >= '0') && (*temp <= '9'))
{
this->_value = this->_value * 10 + (*temp - '0');
this->_pData[iCount++] = *temp++;
}
this->_pData.resize(iCount);
if (cSign == '-')
{
this->_value = 0 - this->_value;
}
if (!this->_IsINT64OverFlow())//溢位
{
this->_value = 0xCCCCCCCCCCCCCCCC;
}
}/*BigData(const char* str)*/
BigData BigData::operator+(const BigData& bigData)
{
if (this->_IsINT64OverFlow() && bigData._IsINT64OverFlow()) //兩個均沒有溢位
{
if (this->_pData[0] != bigData._pData[0])//異號,相加肯定沒有溢位
{
return BigData(this->_value + bigData._value);
}
else //兩個同號
{
if ((this->_value>0 && MAXINT64 - this->_value >= bigData._value) || //結果仍沒有溢位
(this->_value<0 && MININT64 - this->_value <= bigData._value))
{
return BigData(this->_value + bigData._value);
}
}
}
if (this->_pData[0] == bigData._pData[0]) //兩個同號
{
return BigData(this->AddStr(bigData).c_str());
}
BigData temp1((this->_pData).c_str()); //有溢位,異號,呼叫減
BigData temp2((bigData._pData).c_str());
if (this->_pData[0] == '+')
{
temp2._pData[0] = '+';
temp2._value = 0 - temp2._value;
return (temp1.SubStr(temp2)).c_str();
}
else
{
temp1._pData[0] = '+';
temp1._value = 0 - temp1._value;
return (temp2.SubStr(temp1)).c_str();
}
}
std::string BigData::AddStr(const BigData& bigData)const
{
std::string left = this->_pData;
std::string right = bigData._pData;
char cSign = this->_pData[0];
size_t iLSize = left.size();
size_t iRSize = right.size();
if (iLSize < iRSize)
{
std::swap(left, right);
std::swap(iLSize, iRSize);
}
std::string ret;
ret.resize(iLSize + 1);
ret[0] = cSign;
int step = 0;//進位
for (size_t iCount = 1; iCount < iLSize; ++iCount)
{
char ch = left[iLSize - iCount] - '0' + step;
if (iCount < iRSize)
{
ch += (right[iRSize - iCount] - '0');
}
ret[iLSize - iCount + 1] = ch % 10 + '0';
step = ch / 10;
}
ret[1] = step + '0';
return ret;
}
BigData BigData::operator-(const BigData& bigData)
{
if (this->_IsINT64OverFlow() && bigData._IsINT64OverFlow())//無溢位
{
if (this->_pData[0] == bigData._pData[0]) //同號,相減後肯定無溢位
{
return this->_value - bigData._value;
}
else
{
if ((this->_value > 0 && MAXINT64 + bigData._value >= this->_value)||
(this->_value < 0 && MININT64 + bigData._value <= this->_value))
//結果無溢位
{
return this->_value - bigData._value;
}
}
}
if (this->_pData[0] == bigData._pData[0])
{
return BigData(this->SubStr(bigData).c_str());
}
BigData temp((bigData._pData).c_str()); //異號,有溢位 -3-5=-3+(-5) 3-(-5)=3+5
temp._pData[0] = this->_pData[0];
temp._value = 0 - temp._value;
return this->AddStr(temp).c_str();
}/*operator-*/
std::string BigData::SubStr(const BigData& bigData)const
{
std::string ret;
std::string left = this->_pData;
std::string right = bigData._pData;
char cSign = this->_pData[0];
size_t iLSize = left.size();
size_t iRSize = right.size();
if (cSign == '-')
{
std::swap(left, right);
std::swap(iLSize, iRSize);
}
if ((iLSize < iRSize) || (iLSize == iRSize && left < right))
{
std::swap(left, right);
std::swap(iLSize, iRSize);
cSign = '-';
}
else
{
cSign = '+';
}
ret.resize(iLSize);
ret[0] = cSign;
char step = 0;
for (size_t iCount = 1; iCount < iLSize; ++iCount)
{
int ch = left[iLSize - iCount] - '0' - step;
if (iCount < iRSize)
{
ch -= (right[iRSize - iCount] - '0');
}
if (ch < 0)
{
step = 1;
ch = ch + 10;
}
else
{
step = 0;
}
ret[iLSize - iCount] = ch + '0';
}
return ret;
}/*SubStr(const BigData& bigData)*/
BigData BigData::operator*(const BigData& bigData)
{
if (this->_pData[1] == '0' || bigData._pData[1] == '0')
{
return INT64(0);
}
char cSign = '+';
if (this->_pData[0] != bigData._pData[0])
{
cSign = '-';
}
if (this->_pData[1] == '1')
{
std::string ret = bigData._pData;
ret[0] = cSign;
return ret.c_str();
}
if (bigData._pData[1] == '1')
{
std::string ret = this->_pData;
ret[0] = cSign;
return ret.c_str();
}
if (this->_IsINT64OverFlow() && bigData._IsINT64OverFlow()) //沒溢位
{
if ((cSign == '+') && //同號且結果沒溢位
((this->_value > 0 && MAXINT64 / this->_value >= bigData._value) ||
(this->_value < 0 && MAXINT64 / this->_value <= bigData._value)))
{
return this->_value * bigData._value;
}
if ((cSign == '-') && //異號且結果沒溢位
((this->_value > 0 && MININT64 / this->_value <= bigData._value) ||
(this->_value < 0 && MININT64 / this->_value >= bigData._value)))
{
return this->_value * bigData._value;
}
}
return this->MulStr(bigData).c_str();
}
std::string BigData::MulStr(const BigData& bigData)const
{
char cSign = '+';
if (this->_pData[0] != bigData._pData[0])
{
cSign = '-';
}
std::string left = this->_pData;
std::string right = bigData._pData;
size_t iLSize = left.size();
size_t iRSize = right.size();
std::string ret;
ret.resize(iLSize + iRSize - 1);
ret[0] = cSign;
if (iLSize < iRSize)
{
std::swap(left, right);
std::swap(iLSize, iRSize);
}
int step = 0;
for (int iRCount = 0; iRCount < iRSize - 1; ++iRCount)
{
step = 0;
int chR = right[iRSize - 1 - iRCount] - '0';
if (0 == chR)
{
continue;
}
for (int iLCount = 1; iLCount < (int)iLSize; ++iLCount)
{
int ch = chR * (left[iLSize - iLCount] - '0')
+ step + ret[iLSize + iRSize - 1 - iLCount - iRCount];
ret[iLSize + iRSize - 1 - iLCount - iRCount] = ch % 10;
step = ch / 10;
}
ret[iRSize - iRCount - 1] += step;
}
for (int iCount = 1; iCount < iLSize + iRSize - 1; ++iCount)
{
ret[iCount] += '0';
}
return ret.c_str();
}
BigData BigData::operator/(const BigData& bigData)
{
//right == 0
if (bigData._pData[1] == '0')
assert(false);
//left == 0
if (this->_pData[1] == '0')
{
return INT64(0);
}
//無溢位,結果肯定無溢位
if (this->_IsINT64OverFlow() && bigData._IsINT64OverFlow())
{
return this->_value / bigData._value;
}
char cSign = '+';
if (this->_pData[0] != bigData._pData[0])
{
cSign = '-';
}
size_t iLSize = this->_pData.size();
size_t iRSize = bigData._pData.size();
//left < right
if ((iLSize < iRSize) ||
(iLSize == iRSize &&
strcmp(this->_pData.c_str() + 1, bigData._pData.c_str() + 1) < 0))
{
return INT64(0);
}
//right == +1 or -1
if (iRSize == 2 && bigData._pData[1] == '1')
{
std::string ret = this->_pData;
ret[0] = cSign;
return ret.c_str();
}
//left == right
if (strcmp(this->_pData.c_str() + 1, bigData._pData.c_str() + 1) == 0)
{
std::string ret = "+1";
ret[0] = cSign;
return ret.c_str();
}
//有溢位,一般情況
return this->DivStr(bigData).c_str();
}
std::string BigData::DivStr(const BigData& bigData)const
{
char cSign = '+';
if (this->_pData[0] != bigData._pData[0])
{
cSign = '-';
}
size_t iLsize = this->_pData.size();
size_t iRSize = bigData._pData.size();
std::string ret;
ret.append(1, cSign);
std::string leftStr = this->_pData.c_str(); //否則會改變this
std::string rightStr = bigData._pData.c_str();
char* left = (char*)(leftStr.c_str() + 1);
char* right = (char*)(rightStr.c_str() + 1);
int iCount = iRSize - 1;
while (true)
{
int slenLeft = strlen(left);
int slenRight = strlen(right);
if ((slenLeft < slenRight) || (slenLeft == slenRight&&strcmp(left, right) < 0))
{
break;
}
if (!IsLeftStrBig(left, iCount, right, iRSize - 1)) //left < right
{
ret.append(1, '0');
++iCount;
continue;
}
char ch = LoopSub(left, iCount, right, iRSize - 1);
while (*left == '0')
{
++left;
--iCount;
}
++iCount; //取得下一位
ret.append(1, ch);
}
return ret.c_str();
}
char BigData::LoopSub(char* pLeft, int iLSize, const char* pRight, int iRSize)const
{
char ret = '0';
while (IsLeftStrBig(pLeft, iLSize, pRight, iRSize))
{
ret++;
for (int i = iLSize - 1; (i >= 0) && (iRSize + i - iLSize >= 0); --i)
{
pLeft[i] -= (pRight[iRSize + i - iLSize] - '0');
if (pLeft[i] < '0')
{
pLeft[i] += 10;
--pLeft[i - 1];
}
}//for
//去0 eg:0334
while (*pLeft == '0')
{
++pLeft;
--iLSize;
}
}//while
return ret;
}
bool BigData::IsLeftStrBig(const char* pLeft, int iLSize, const char* pRight, int iRSize)const
{
if ((iLSize > iRSize) ||
(iLSize == iRSize && strcmp(pLeft, pRight) >= 0))
{
return true;
}
return false;
}
void BigData::_Int64ToStr()
{
char cSign = '+';
if (this->_value < 0)
{
cSign = '-';
}
this->_pData.append(1, cSign);
if (this->_value == 0)
{
this->_pData.append(1, '0');
return;
}
INT64 temp = this->_value;
while (temp)
{
this->_pData.append(1, (temp % 10 + '0'));
temp /= 10;
}
char* left = (char*)(this->_pData.c_str() + 1);
char* right = left + this->_pData.size() - 2;
while (left < right)
{
char ch = *left;
*left++ = *right;
*right-- = ch;
}
}/*void BigData::_Int64ToStr()*/
bool BigData::_IsINT64OverFlow()const
{
std::string max = "+9223372036854775807";
std::string min = "-9223372036854775808";
size_t size = this->_pData.size();
if (size < max.size())
{
return true;
}
if ((this->_pData[0] == '+') && (size == max.size()) && (this->_pData <= max))
{
return true;//返回true沒有溢位
}
if ((this->_pData[0] == '-') && (size == min.size()) && (this->_pData <= min))
{
return true;
}
return false;
}/*bool BigData::_IsINT64OverFlow()const*/
std::ostream& operator<<(std::ostream& _cout, const BigData& bigData)
{
if (bigData._IsINT64OverFlow())//沒有溢位
{
_cout << bigData._value << std::endl;
}
else
{
if (bigData._pData[0] == '+')
{
_cout << bigData._pData.c_str() + 1 << std::endl;
}
else
{
_cout << bigData._pData << std::endl;
}
}
return _cout;
}
相關文章
- shell加減乘除運算
- MongoDB 中的【加減乘除】運算MongoDB
- Verilog實現加減乘除運算
- 位運算實現加減乘除
- 浮點數的加減乘除運算細節
- 三個數字的加減乘除模運算
- NumPy 簡單算術:加減乘除及其他運算
- 二進位制運算加減乘除+快速冪
- 超大整數的加減乘除計算方法
- FPGA中加減乘除運算的注意問題FPGA
- JavaScript浮點數加減乘除精確計算JavaScript
- 7-2 算術入門之加減乘除
- 簡單的加減乘除(遞迴)遞迴
- 79 不用加減乘除做加法
- BigDecimal加減乘除運算,保留2位小數點,初始化,與0的比較Decimal
- JS加減乘除位移方法封裝JS封裝
- JavaScript加減乘數運算JavaScript
- JS 加減乘除 尤其是減法精度問題JS
- 大數模擬 加減乘除 判斷大數是否為素數 板子
- java的多項式的加減乘除和賦值Java賦值
- 高精度四件套(加減乘除)
- 每日一練(34):不用加減乘除做加法
- Python運算子可不只有加減乘除Python
- 【劍指offer】65. 不用加減乘除做加法
- [每日一題] 第六題:不用加減乘除做加法每日一題
- LeetCode 劍指 Offer 65. 不用加減乘除做加法LeetCode
- 【oracle】日期加減計算Oracle
- C++筆記:輸入輸出、變數、變數加減乘除C++筆記變數
- 大數運算—大數加法、減法、乘法、除法詳解
- 資料的運算(上)
- 利用Python自動生成小學生加減乘除口算考試題卷,不再為手寫算術題煩惱!Python
- 大資料教程:Transformation和Action運算元演示大資料ORM
- ABAP面試問題 - 不使用加減乘除等操作比較兩個整數大小面試
- 請寫一個整數計算器,支援加減乘三種運算和括號。Python版本Python
- excel日期加減計算方法 excel計算日期時間差Excel
- mysql查詢中時間、日期加減計算MySql
- 計算機組成原理浮點數加減計算機
- 不同型別資料運算型別
- 結構化資料上的 TopN 運算