浅析《大数据运算》-加减乘除以及模除运算
发表于:2025-01-24 作者:千家信息网编辑
千家信息网最后更新 2025年01月24日,WAY?为什么会有大数据运算?缘由?在c++中常用的数据类型有 char:1 bit,short 2 bit,int 4 bit,long long 8 bit等等,以上数据类型标识的数据大小非常有限
千家信息网最后更新 2025年01月24日浅析《大数据运算》-加减乘除以及模除运算
WAY?
为什么会有大数据运算?缘由?
在c++中常用的数据类型有 char:1 bit,short 2 bit,int 4 bit,long long 8 bit等等,以上数据类型标识的数据大小非常有限,如果遇到大于他们能表示的范围时,计算结果就会有误,日常生活中的计算器也是如此,我国计算两个比较大的数的运算,也会出现错误,或者不能正常显示,
例如计算123456789123456789*987654321987654321
计算结果如下:
具体区别如下:
分析:
在数据运算中会出现两种情况:一种是数据、且小计算结果不会溢出;另一种是数据溢出或者计算结果会溢出;
所以为了计算便捷,也为了节省运算量,我设置了如下两种储存数据方式,并且在计算也分情况不同而选择不同方法,形式如下:
做了什么?
为了解决上述问题,我写了一个计算大数据四则运算以及求模的小项目,实现的功能有 + - * / %;
主要的接口以及实现代码如下:
程序头文件以及接口如下:
/*** 项目名称:大数据运算* 接口名称:BigData.h* 作 者: 邹明* 完成时间:2016.04.12**/#ifndef __BIG_DATA_H__#define __BIG_DATA_H__#includeusing namespace std;#include #include #define MAX_INT64 0x7FFFFFFFFFFFFFFF //小数据能表示的最大值#define MIN_INT64 0x8000000000000000 //小数据能表示的最小值#define INIT 0xcccccccccccccccctypedef long long INT64;class BigData{public: BigData(INT64 value= INIT); BigData(const char*ptrData); //运算符重载 BigData operator+(const BigData& bigdata); BigData operator-(const BigData& bigdata); BigData operator*(const BigData& bigdata); BigData operator/(const BigData& bigdata); BigData operator%(const BigData& bigdata);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); std::string Mod(std::string left, std::string right); //求模 bool IsINT64OverFlow() const; //判断是否越界 void INT64ToString(); //数据转化为字符串 bool IsLeftStrBig(const char *pLeft, int LSise, const char *pRight, int RSise); //比较左操作数是否大于有操作数 char SubLoop(char *pLeft, int LSise, const char *pRight, int RSise); //除法时每次求商运算 friend std::ostream&operator<<(std::ostream & cout, const BigData& bigdata); //输出运算符重载private: INT64 _value; //×××数据形式 string _strData; //字符串数据形式};#endif
实现代码,文件名称BigData.cpp,下面文件晕包含于此内
构造函数,转化字符串,判断越界,输出运算符重载等函数
#include"BigData.h"BigData::BigData(INT64 value) //小数据构造函数 :_value(value){ INT64ToString();}BigData::BigData(const char*ptrData)//大数据构造函数{ //123456 //+1223356 //122334qwer //qwee123 //0000qwer assert(ptrData); char *pstr = (char*)ptrData; char cSymbol = '+'; if (('+' == *pstr) || ('-' == *pstr)) { cSymbol = *pstr; pstr++; } else if (('0' <= *pstr)&&('9' >= *pstr)) { cSymbol = '+'; } else if (*pstr == ' ') { while (*pstr == ' ') { pstr++; } if (('+' == *pstr) || ('-' == *pstr)) { cSymbol = *pstr; pstr++; } else if (('0' <= *pstr) && ('9' >= *pstr)) { cSymbol = '+'; } } else { return; } while (' ' == *pstr) pstr++; while ('0' == *pstr) pstr++; _strData.resize(strlen(ptrData)+1); _strData[0] = cSymbol; _value = 0; int iCount = 1; while ((*pstr >= '0') && (*pstr <= '9')) { _value = _value * 10 + (*pstr - '0'); _strData[iCount] = *pstr; pstr++; iCount++; } _strData.resize(iCount); if (cSymbol == '-') { _value = 0 - _value; }}void BigData::INT64ToString() //将数据的数值填充至字符串部分{ char cSymbl = '+'; if (_value < 0) { cSymbl = '-'; } //1234567 //7654321 _strData.append(1, cSymbl); INT64 temp = _value; if (temp < 0) { temp = 0 - temp; } while (temp) { _strData.append(1, temp % 10 + '0'); temp /= 10; } char *pleft = (char*)_strData.c_str() + 1; char *pright = pleft + _strData.size() - 2; while (pleft < pright) { char tem = *pleft; *pleft = *pright; *pright = tem; pleft++; pright--; }}bool BigData::IsINT64OverFlow()const //判断是否越界{ std::string temp("+9223372036854775807"); if ('-' == _strData[0]) { temp = "-9223372036854775808"; } if (_strData.size() < temp.size()) { return true; } else if ((_strData.size() == temp.size()) && (_strData <= temp)) { return true; } return false;}//求商char BigData::SubLoop(char *pLeft, int LSize, const char *pRight, int RSize){ assert(pLeft); assert(pRight); char cRet = '0'; while (true) { while ((*pLeft == '0')&&LSize>0) { pLeft++; LSize--; } if (!IsLeftStrBig(pLeft, LSize, pRight, RSize)) { break; } for (int i = 1;i<=LSize; i++) { if ((LSize > RSize) && (i == LSize)) { break; } char ret = pLeft[LSize - i]; ret -= pRight[RSize - i]; if (ret < 0) { pLeft[LSize - i - 1] -= 1; ret += 10; } pLeft[LSize - i] = ret+'0'; } cRet++; } return cRet;}//判断左操作数是否大于右操作数bool BigData::IsLeftStrBig(const char *pLeft, int LSise, const char *pRight, int RSise){ if (LSise > RSise || ((LSise == RSise) && (strcmp(pLeft, pRight) >= 0))) { return true; } return false;}//输出运算符重载std::ostream&operator<<(std::ostream & _cout, const BigData& bigdata){ if (bigdata.IsINT64OverFlow()) { _cout << bigdata._value; } else { char *pData = (char*)bigdata._strData.c_str(); if ('+' == pData[0]) { pData++; } _cout << pData; } return _cout;}
加运算
BigData BigData::operator+(const BigData& bigdata) //+ 加法运算符重载{ if (IsINT64OverFlow() && bigdata.IsINT64OverFlow()) { if (_strData[0] != bigdata._strData[0]) { return BigData(_value + bigdata._value); } else { INT64 temp_max = MAX_INT64 - _value; INT64 temp_min = MIN_INT64 - _value; //10 -3 =7 5 //(-10)-(-3)=-7 -5 if (((_value >= 0) && (temp_max >= bigdata._value)) || ((_value < 0) && (temp_min <= bigdata._value))) { return BigData(_value + bigdata._value); } } } if (_strData[0] == bigdata._strData[0]) { return BigData(Add(_strData, bigdata._strData).c_str()); } else { if(_strData[0] == '+') { string ptr(bigdata._strData); ptr[0] = '+'; return Sub(_strData, ptr).c_str(); } else { string ptr(_strData); ptr[0] = '+'; return Sub(bigdata._strData, ptr).c_str(); } }}std::string BigData::Add(std::string left, std::string right){ int iLsize = left.size(); int iRsize = right.size(); char cSymbol = left[0]; //取得符号位 if (iLsize < iRsize) { std::swap(left, right); std::swap(iLsize, iRsize); } std::string sRet; sRet.resize(iLsize + 1); char Step = 0; for (int i = 1; i < iLsize; i++) { char cRet = left[iLsize - i] - '0' + Step; if (i < iRsize) { cRet += (right[iRsize - i] - '0'); } sRet[iLsize - i + 1] = cRet % 10 + '0'; Step = cRet / 10; } sRet[1] = Step + '0'; sRet[0]=cSymbol; return sRet;}
减运算:
BigData BigData::operator-(const BigData& bigdata) //- 减法运算符重载{ if (IsINT64OverFlow() && bigdata.IsINT64OverFlow()) { if (_strData[0] == bigdata._strData[0]) { return BigData(_value - bigdata._value); } else { INT64 temp_max = _value - MAX_INT64; INT64 temp_min = _value - MIN_INT64; //10 -3 =7 5 //(-10)-(-3)=-7 -5 if (((_value >= 0) && (temp_max <= bigdata._value)) || ((_value < 0) && (temp_min >= bigdata._value))) { return BigData(_value - bigdata._value); } } } if (_strData[0] == bigdata._strData[0]) { return BigData(Sub(_strData, bigdata._strData).c_str()); } else { string ptr(bigdata._strData); ptr[0] = _strData[0]; return Add(_strData, ptr).c_str(); }}std::string BigData::Sub(std::string left, std::string right){ int iLsize = left.size(); int iRsize = right.size(); int Max_size = iLsize; std::string sRet; char cSymbol = left[0]; //取符号位 if (iLsize <= iRsize) { if ((iLsize == iRsize) && (strcmp(left.c_str() ,right.c_str())<0) && (left[0] == right[0])) { if ('+' == right[0]) { cSymbol = '-'; } else { cSymbol = '+'; } Max_size = iRsize; std::swap(left, right); std::swap(iLsize, iRsize); } } else { cSymbol = left[0]; Max_size = iLsize; } char Step = 0; sRet.assign(Max_size, 48); for (int i = 1; i < Max_size; i++) { char cRet = 0; if (0<(iLsize - i)) { cRet = left[iLsize - i] - '0' + Step; } if (i < iRsize) { if (cRet < right[iRsize - i] - '0') { cRet += 10; } Step = 0 - (cRet-Step) / 10; cRet -= (right[iRsize - i] - '0'); } sRet[Max_size - i ] = cRet + '0'; } sRet[0] = cSymbol; return sRet;}
乘运算:
BigData BigData::operator*(const BigData& bigdata){ if ((0 == _value)||(0==bigdata._value)) { return BigData(INT64(0)); } if (IsINT64OverFlow() && bigdata.IsINT64OverFlow()) { if (_strData[0] == bigdata._strData[0]) { if (((_value > 0) && ((long long)MAX_INT64 / _value >= bigdata._value)) || ((_value < 0) && ((long long)MAX_INT64 / _value <= bigdata._value))) //同号相乘 结果为正 { return BigData(_value*bigdata._value); } } else { if (((_value > 0) && ((long long)MIN_INT64 / _value <= bigdata._value)) || ((_value < 0) && ((long long)MIN_INT64 / _value >= bigdata._value))) //异号相乘 结果为负 { return BigData(_value*bigdata._value); } } } return BigData(Mul(_strData, bigdata._strData).c_str());}std::string BigData::Mul(std::string left, std::string right){ char cSymbol = '+'; //设置符号位 int iLsize = left.size(); int iRsize = right.size(); if (left[0] == right[0]) cSymbol = '+'; else cSymbol = '-'; if (iLsize > iRsize) { std::swap(left, right); std::swap(iLsize, iRsize); } std::string sRet; int t = 1; if (((left[1] - '0')*(right[1] - '0') +(left[1] - '0')*(right[1] - '0'))<10) { t = 2; } else t = 1; //sRet.resize(iLsize + iRsize - t); sRet.assign(iLsize + iRsize - t,'0'); int sizeRet = iLsize + iRsize - 1; sRet[0] = cSymbol; int i = 1, j = 1; for (i = 1, j = 1; i < iLsize; i++) { char step = 0; char cleft = left[iLsize - i] - '0'; for (int j = 1; j < iRsize; j++) { char cRet = cleft*(right[iRsize - j] - '0') + step + (sRet[sizeRet - i - j + 1] - '0'); step = cRet / 10; sRet[sizeRet - i - j + 1] = cRet + '0'; if ((j+1)==iRsize) sRet[sizeRet - i - j] = step+'0'; } } return sRet;}
除运算:
BigData BigData::operator/(const BigData& bigdata){ if (bigdata._strData[1] == '0') { cout << "除数为 0 " << endl; assert(0); } if (_strData[1] == 0) return INT64(0); if ((IsINT64OverFlow()) && bigdata.IsINT64OverFlow()) { return _value / bigdata._value; } if (_strData.size() < bigdata._strData.size()) { return INT64(0); } else if (_strData.size() == bigdata._strData.size()) { if (strcmp(_strData.c_str() + 1, bigdata._strData.c_str() + 1) < 0) return INT64(0); if (strcmp(_strData.c_str() + 1, bigdata._strData.c_str() + 1) == 0) { if (_strData[0] == bigdata._strData[0]) return INT64(1); else return INT64(-1); } } return BigData(Div(_strData, bigdata._strData).c_str());}std::string BigData::Div(std::string left, std::string right){ 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 DataLen = right.size() - 1; int Lsize = left.size() - 1; for (int i = 0; i < Lsize; i++) { if (!IsLeftStrBig(pLeft, DataLen, pRight, right.size()-1)) { sRet.append(1, '0'); DataLen++; } else { sRet.append(1, SubLoop(pLeft, DataLen, pRight, right.size() - 1)); } if (DataLen + i>Lsize) { break; } if (*pLeft == '0') { pLeft++; } else { DataLen = right.size(); } } return sRet;}
摸除运算:
BigData BigData:: operator%(const BigData& bigdata){ if (bigdata._strData[1] == '0') { cout << "除数为 0 或对0求模" << endl; assert(0); } if (_strData[1] == 0) return INT64(0); if ((IsINT64OverFlow()) && bigdata.IsINT64OverFlow()) { return _value % bigdata._value; } if (_strData.size() < bigdata._strData.size()) { return BigData(_strData.c_str()); } else if (_strData.size() == bigdata._strData.size()) { if (strcmp(_strData.c_str() + 1, bigdata._strData.c_str() + 1) < 0) return INT64(0); if (strcmp(_strData.c_str() + 1, bigdata._strData.c_str() + 1) == 0) { return INT64(0); } } return BigData(Mod(_strData, bigdata._strData).c_str());}std::string BigData::Mod(std::string left, std::string right){ char cSymbol = left[0]; BigData n1(left.c_str() + 1); BigData n2(right.c_str() + 1); BigData n3 = n1 / n2; BigData n4 = n3*n2; BigData sRet(n1 - n4); sRet._strData[0] = cSymbol; return sRet._strData;}
测试用例,文件名test.cpp
#include"BigData.h"void Test1(){ BigData n1(123456); BigData b2("12346678"); BigData b3("+12346678"); BigData b4("-123466"); BigData b5("+"); BigData b6(" "); BigData b7("12346aaaa"); BigData b8("+asd12346678"); BigData b9("000012346678"); cout << "n1:" << n1 << endl; cout << "b2:" << b2 << endl; cout << "b3:" << b3 << endl; cout << "b4:" << b4 << endl; cout << "b5:" << b5 << endl; cout << "b6:" << b6 << endl; cout << "b7:" << b7 << endl; cout << "b8:" << b8 << endl; cout << "b9:" << b9 << endl;}void testAdd(){ BigData b1("-45353"); BigData b2("37353753"); BigData b3("- 9223372036854775808"); BigData b4(" 9223372036854775800"); BigData b5(" -9223372036854775810"); BigData b6("9223372036854775900"); //1、都在INT64范围内 cout << (b1 + b1) << endl; cout << (b2 + b2) << endl; cout << (b1 + b2) << endl; cout << "b4:" << b4 << endl; cout << (b1 + b4) << endl; cout << b3 << endl; cout << (b1 + b3) << endl; cout << (b2 + b4) << endl; //2、都不在INT64范围内 cout << (b2 + b5) << endl; cout << (b1 + b6) << endl; cout << (b6 + b1) << endl;}void testSub(){ BigData b1("-45353"); BigData b2("37353753"); BigData b3("-9223372036854775808"); BigData b4("9223372036854775800"); BigData b5("-9223372036854775810"); BigData b6("9223372036854775900"); //1、都在INT64范围内 cout << (b1 - b2) << endl; cout << (b2 - b1) << endl; cout << (b3 - b1) << endl; cout << (b1 - b4) << endl; cout << (b3 - b2) << endl; cout << (b4 - b1) << endl; cout << (b1 - b3) << endl; cout << (b2 - b4) << endl; cout << endl; //2、一个在一个不在<运算后在范围内,运算后不在范围内> cout << (b5 - b1) << endl; cout << (b1 - b5) << endl; cout << endl; cout << (b6 - b2) << endl; cout << (b2 - b6) << endl; cout << endl; cout << (b6 - b5) << endl; cout << (b5 - b6) << endl; cout << (b2 - b5) << endl; cout << (b1 - b6) << endl; cout << (b6 - b1) << endl;}void testMul(){ BigData b1("-45353"); BigData b2("37353753"); BigData b3("-9223372036854775808"); BigData b4(" 9223372036854775800"); BigData b5("-9223372036854775810"); BigData b6(" 9223372036854775900"); //1、都在INT64范围内 cout << (BigData("999") * BigData("22222222222222222222222222222")) << endl; cout << (b2 * b1) << endl; cout << (b1 * b2) << endl; cout << (b1 * BigData("0")) << endl; cout << (BigData("0") * b2) << endl; cout << endl; cout << (b3 * b1) << endl; cout << (b1 * b3) << endl; cout << (b1 * b4) << endl; cout << (b4 * b1) << endl; cout << (b3 * b2) << endl; cout << (b2 * b4) << endl; cout << endl; //2、一个在一个不在<运算后在范围内,运算后不在范围内> cout << (BigData("0") * b6) << endl; cout << (b5 * BigData("0")) << endl; cout << (b5 * b1) << endl; cout << (b1* b5) << endl; cout << endl; cout << (b6 * b2) << endl; cout << (b2 * b6) << endl; cout << endl; cout << (b6 * b5) << endl; cout << (b5 * b6) << endl; cout << (b2 * b5) << endl; cout << endl; cout << (b1 * b6) << endl; cout << (b6 * b1) << endl;}void testDiv(){ BigData b1("-45353"); BigData b2("37353753"); BigData b3("-9223372036854775808"); BigData b4(" 9223372036854775800"); BigData b5("-9223372036854775810"); BigData b6(" 9223372036854775900"); BigData b7("-1231123203367738338252"); //1、排除除数为0 cout << (b1 / BigData(0)) << endl; //2、在范围内 cout << (b1 / b2) << endl; cout << (b2 / b1) << endl; //3、不在范围内<左(被除数)比右(除数)小为0,左比右大> cout << (b2 / b5) << endl; cout << (b2 / b6) << endl; cout << (b5 / b2) << endl; cout << (b6 / b2) << endl; cout << (b6 / b1) << endl; cout << (b5 / b1) << endl; cout << b7 / b1 << endl;}void testMod(){ BigData b1("-45353"); BigData b2("37353753"); BigData b3("-9223372036854775808"); BigData b4(" 9223372036854775800"); BigData b5("-9223372036854775810"); BigData b6(" 9223372036854775900"); BigData b7("-1231123203367738338252"); //1、排除除数为0 cout << (b1 / BigData(0)) << endl; //2、在范围内 cout << (b1 % b2) << endl; cout << (b2 % b1) << endl; //3、不在范围内 cout << (b2 % b5) << endl; cout << (b2 % b6) << endl; cout << (b5 % b2) << endl; cout << (b6 % b2) << endl; cout << (b6 % b1) << endl; cout << (b5 % b1) << endl; cout << b7 % b1 << endl;}int main(){ //testAdd(); //测试+ //testSub(); //测试- //testMul(); //测试 * //testDiv(); //测试 / testMod(); //测试% system("pause"); return 0;}
运行结果:
加运算:
减运算:
乘运算:
除运算:
模除运算:
以上代码均为原创,实现了与小数据运算同样的功能,如果发现错误,欢迎各位读者批评指正,谢谢
运算
数据
范围
结果
运算符
测试
函数
字符
字符串
文件
除数
代码
名称
形式
接口
符号
输出
不同
功能
情况
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
滴滴软件开发商
广东现代软件开发成本价
网络安全的目的要点
黟县软件开发文档
阿里服务器端口管理
软件开发经理 看哪些书
苏州可视化智慧工厂软件开发
软件开发项目管理考什么证
中兴通讯服务器经销商
网络安全法正式实施图片
江阴网络营销软件开发质量服务
计算机网络技术相近专业
国外防攻击服务器租用
产品经理软件开发进度管理
泰康人寿软件开发岗
服务器设备io性能低
成都阿里宝网络技术有限公司
mpls虚拟专用网络技术
打开核磁数据库
qq浏览文件服务器
大学计算机网络技术基础知识
国产化服务器供应厂家
软件开发 女 33岁了
软件开发质量控制岗
斑马神仙软件开发
2021邮储银行服务器招标
《数据库应用技术教程》
数据库中的预测得分怎么分析
魔兽世界新服务器如何升级
学软件开发去当兵