C++项目之大数四则运算

来源:互联网 发布:淘宝差评可以删除吗 编辑:程序博客网 时间:2024/04/27 21:30
项目描述 : 实现大数的读入,输出,实现大数的加,减,乘,除,取模和比较运算。
开发技术:string,C++类
项目特点: 1. 使用C++类将超过long long int所能存储的范围的数转换成字符串进行存储。
2. 将存储大数的字符串拆开进行分析,逐位进行运算储存。
3. 实现大数的读入,输出以及大数的加,减,乘,除,取模和比较运算。
4. 将大数问题分解成单个字符的相互运算。


1.头文件:
#ifndef BIG_DATA_H#define BIG_DATA_H#include <string>#include <iostream>using namespace std;#define UN_INIT 0xcccccccccccccccc#define MAX_INT64 0x7fffffffffffffff#define MIN_INT64 0x8000000000000000typedef long long INT64;class BigData{public:BigData(INT64 data = UN_INIT);BigData(const char *pData);BigData operator+(BigData& bigData);BigData operator-(const BigData& bigData);BigData operator*(const BigData& bigData);BigData operator/(const BigData& bigData);BigData operator%(const BigData& bigData);//=======================================bool operator<(const BigData& bigData);bool operator>(const BigData& bigData);bool operator==(const BigData& bigData);friend std::ostream& operator<<(std::ostream& _cout, const BigData& bigData);friend std::istream& operator>>(std::istream& _cin, BigData bigData);bool IsINT64Overflow()const;private: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);void INT64ToString();bool IsLeftStrBig(char *pLeft, size_t LSize, char *pRight, size_t RSize);char SubLoop(char *&pLeft, int& LSize, char *pRight, size_t RSize);private:INT64 m_llValue;std::string m_strData; };#endif

2.算法的实现

#include "BigData.h"#include <cassert>BigData::BigData(INT64 data): m_llValue(data), m_strData(""){INT64ToString();}int idx = 0;BigData::BigData(const char *_pdata){assert(_pdata);char csymbol = _pdata[0];char* pdata = (char*)_pdata;if (csymbol == '+' || csymbol == '-'){pdata++;}else if (*pdata >= '0'&& *pdata <= '9'){csymbol = '+';}else{m_llValue = 0;m_strData = '0';return;}while (*pdata == '0'){pdata++;}m_strData.resize(strlen(pdata) + 1);m_llValue = 0;m_strData[0] = csymbol;int count = 1;while (pdata){if (*pdata >= '0' && *pdata <= '9'){m_llValue = m_llValue * 10 + *pdata - '0';m_strData[count++] = *pdata++;}else{break;}}//m_strData.resize(count);if ('-' == csymbol){m_llValue = 0 - m_llValue;}}BigData BigData::operator+(BigData& bigData){if (!IsINT64Overflow() && !bigData.IsINT64Overflow()){if (m_strData[0] != bigData.m_strData[0]){return BigData(m_llValue + bigData.m_llValue);}else{if ((m_strData[0] == '+' && MAX_INT64 - m_llValue >= bigData.m_llValue|| (m_strData[0]) == '-' && MIN_INT64 - m_llValue <= bigData.m_llValue)){return BigData(m_llValue + bigData.m_llValue);}}}std::string strret;if (m_strData[0] == bigData.m_strData[0]){strret = Add(m_strData, bigData.m_strData);}else{strret = Sub(m_strData, bigData.m_strData);}return BigData(strret.c_str());}BigData BigData::operator-(const BigData& bigData){if (!IsINT64Overflow() && !bigData.IsINT64Overflow()){if (m_strData[0] == bigData.m_strData[0]){return BigData(m_llValue - bigData.m_llValue);}else{if ((m_strData[0] == '+' && MAX_INT64 + bigData.m_llValue >= m_llValue)|| (m_strData[0] == '-' && MIN_INT64 + bigData.m_llValue <= m_llValue)){return BigData(m_llValue - bigData.m_llValue);}}}std::string strret;if (m_strData[0] != bigData.m_strData[0]){strret = Add(m_strData, bigData.m_strData);}else{strret = Sub(m_strData, bigData.m_strData);}return BigData(strret.c_str());}BigData BigData::operator*(const BigData& bigData){if (m_llValue == 0 || bigData.m_llValue == 0){return BigData(INT64(0));}if (!IsINT64Overflow() && !bigData.IsINT64Overflow()){if (m_strData[0] == bigData.m_strData[0]){if ((m_strData[0] == '+' && MAX_INT64 / m_llValue >= bigData.m_llValue)|| (m_strData[0] == '-' && MAX_INT64 / m_llValue <= bigData.m_llValue)){return BigData(m_llValue * bigData.m_llValue);}}else{if ((m_strData[0] == '+' && MIN_INT64 / m_llValue <= bigData.m_llValue)|| (m_strData[0] == '-' && MIN_INT64 / m_llValue >= bigData.m_llValue)){return BigData(m_llValue * bigData.m_llValue);}}}return BigData(Mul(m_strData, bigData.m_strData).c_str());}BigData BigData::operator/(const BigData& bigData){if (bigData.m_llValue == 0){assert("除数不能为0");return BigData(INT64(0));}if (!IsINT64Overflow() && bigData.IsINT64Overflow()){return BigData(m_llValue / bigData.m_llValue);}return BigData(Div(m_strData, bigData.m_strData).c_str());}std::string BigData::Add(std::string left,std::string right){int lsize = left.size();int rsize = right.size();char ch = left[0];if (lsize < rsize){std::swap(left,right);std::swap(lsize,rsize);}std::string strret;strret.resize(lsize + 1);strret[0] = ch;char cstep = 0;int n = 1;while (n < lsize){char cret = left[lsize - n] - '0' + cstep;if (n < rsize){cret += right[rsize - n] - '0';}strret[lsize - n + 1] = (cret % 10 + '0');cstep = cret / 10;n++;}strret[1] = cstep + '0';return strret;}std::string BigData::Sub(std::string left, std::string right){int lsize = left.size();int rsize = right.size();char csymbol = left[0];if ((lsize < rsize) ||(lsize == rsize && left < right)){std::swap(left, right);std::swap(lsize, rsize);if (csymbol == '+'){csymbol = '-';}else{csymbol = '+';}}std::string strret;strret.resize(lsize);strret[0] = csymbol;int n = 1;while (n < lsize){char cret = left[lsize - n] - '0';if (n < rsize){cret -= right[rsize - n] - '0';}if (cret < 0){left[lsize - n - 1] -= 1;cret += 10;}strret[lsize - n] = (cret + '0');n++;}return strret;}std::string BigData::Mul(std::string left, std::string right){int lsize = left.size();int rsize = right.size();if (lsize > rsize){swap(left, right);swap(lsize, rsize);}char csymbol = '+';if (left[0] != right[0]){csymbol = '-';}string strret;strret.assign(lsize + rsize - 1, '0');strret[0] = csymbol;int datalen = strret.size();int ioffset = 0;for (int lidx = 1; lidx < lsize; lidx++){char cleft = left[lsize - lidx] - '0';char cstep = 0;if (cleft == 0){ioffset++;continue;}for (int ridx = 1; ridx < rsize; ridx++){char cret = cleft*(right[rsize - ridx]-'0');cret += cstep;cret += (strret[datalen - ioffset - ridx] - '0');strret[datalen - ioffset - ridx] = (cret % 10 + '0');cstep = cret / 10;} strret[datalen - ioffset - rsize] += cstep;ioffset++;}return strret;}std::string BigData::Div(std::string left, std::string right){char lsize = left.size();char rsize = right.size();char csymbol = '+';if (left[0] != right[0]){csymbol = '-';}if ((lsize < rsize) || (lsize == rsize && strcmp(left.c_str() + 1, right.c_str() + 1) < 0)){return "0";}else{if (right == "-1" || right == "+1"){left[0] = csymbol;return left;}}string strret;strret.append(1, csymbol);char *pleft = (char*)(left.c_str() + 1);char *pright = (char*)(right.c_str() + 1);int datalen = 1;lsize -= 1;for (idx = 0; idx < lsize;){if (*pleft == '0'){strret.append(1, '0');pleft++;idx++;continue;}if (!IsLeftStrBig(pleft, datalen, pright, rsize - 1)){strret.append(1, '0');datalen++;if (idx + datalen > lsize){break;}continue;}  else{strret.append(1,SubLoop(pleft, datalen, pright ,rsize - 1));datalen++;}}return strret;}void BigData::INT64ToString(){char csymbol = '+';INT64 tmp = m_llValue;if (tmp < 0){csymbol = '-';tmp = 0 - tmp;}m_strData.append(1, csymbol);while (tmp){  m_strData.append(1,tmp%10 + '0');tmp /= 10;}char *left = (char*)(m_strData.c_str() + 1);char *right = (char*)(m_strData.c_str() + m_strData.size() - 1);while (left < right){char ctmp = *left;*left++ = *right;*right-- = ctmp;}}bool BigData::IsINT64Overflow()const {std::string tmp;if ('+' == m_strData[0]){tmp = "+9223372036854775807";}else{tmp = "-9223372036854775808";}if ((m_strData.size() > tmp.size()) ||((m_strData.size() == tmp.size())&&(m_strData > tmp))){return true;}return false;}bool BigData::IsLeftStrBig(char *pLeft, size_t LSize, char *pRight, size_t RSize){assert(pLeft != NULL && pRight != NULL);if ((LSize > RSize) ||(LSize == RSize && strncmp(pLeft,pRight,LSize) >= 0)){return true;}return false;}char BigData::SubLoop(char *&pLeft, int& LSize, char *pRight, size_t 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){if (pLeft[ldatalen] < pRight[rdatalen]){pLeft[ldatalen - 1] -= 1;pLeft[ldatalen] += 10;}pLeft[ldatalen] = pLeft[ldatalen] - pRight[rdatalen] + '0';ldatalen--;rdatalen--;}while ((*pLeft == '0') && (LSize > 0)){pLeft++;LSize--;idx++;}cret++;}return cret;}std::ostream& operator<<(std::ostream& _cout, const BigData& bigData){if (!bigData.IsINT64Overflow()) // 没有溢出{_cout << bigData.m_llValue;}else{char* pData = (char*)bigData.m_strData.c_str();if (pData[0] == '+'){pData++;}_cout << pData;}return _cout;}



1 0
原创粉丝点击