首先,让我们先来熟悉一下两种防止头文件被重复引用的处理#pragma once和#ifndef的区别


http://10739786.blog.51cto.com/10729786/1730827


接下来,开始我们的主题 <大数运算>
在平时生活中细心的你可能会发现,好多时候我们使用计算器时,总有一个显示的最大值,当计算超过这个值时就不能再计算了,那如果我们想要计算更大的数值要怎么办?


本文通过C++编程实现 大数的加减乘除四则运算


<思路与方法同样都在程序内部>

这次通过标准的三个文件来实现声明<BIGDATA.h>、定义实现函数功能<BIGDATA.cpp>、测试<test.cpp>


<BIGDATA.h>

#pragmaonce#ifndef__BIGDATA_H__#define__BIGDATA_H__#define_CRT_SECURE_NO_WARNINGS1#include<iostream>usingnamespacestd;#include<string.h>#include<assert.h>//1、考虑当数值小时,运算速度尽量贴近内置类型(所以,结构会有两个-->内置类型longlong及大数的char*)//2、构造时可能的输入{"1234""0001234""1564adf""""+(-)12345"}//typedeflonglongINT64;//stringMAX_INT64="9223372036854775807";//stringMIN_INT64="-9223372036854775808";//enum{MAX_INT64=9223372036854775807,MIN_INT64=-9223372036854775808};//不行enum后是int类型//constINT64MAX_INT64=0x7fffffffffffffff;//9223372036854775807;constINT64MIN_INT64=0x8000000000000000;//-9223372036854775808;classBigData{public:BigData(INT64value=0);BigData(conststringpData);BigDataoperator+(constBigDatabigdata);BigDataoperator-(constBigDatabigdata);BigDataoperator*(constBigDatabigdata);BigDataoperator/(constBigDatabigdata);~BigData();voidPrint();private:boolPDataIsOverINT64()const;friendstd::ostream&operator<<(std::ostream&_cout,constBigData&bigdata);//不能在_cout前加const->_cout<<10<<endl;将不能通过BigDataAdd(stringpData1,stringpData2);//并不一定要写成成员函数(也可以写成一般函数被使用)BigDataSub(stringpData1,stringpData2);BigDataMul(stringpData1,stringpData2);BigDataDiv(stringpData1,stringpData2);private:INT64_value;string_pData;};#endif__BIGDATA_H__//<BIGDATA.cpp>#include"BIGDATA.h"BigData::BigData(INT64value)//若输入的数值位数大于MAX_DATA,系统编译不通过,当位数一致且大于时,转为负,无能为力:_value(value){//在_pData中加入valuevoidInvert(string&pdata);size_ti=0;INT64tmp=0;_pData.append(1,'+');if(value<0){_pData[0]='-';value*=-1;}while(value!=0){tmp=value%10;_pData.append(1,(char)(tmp+'0'));value/=10;}Invert(_pData);}BigData::BigData(conststringpData){//解决各种特殊情况//{"1234""0001234""1564adf""""+(-)12345"NULL}//参考atoi()函数处理办法//跳过符号将输入字符串都归为一般////判是否是数字字符isdigit(intc)是-1/否0还有判空字符(宏定义)isspace(intc)头文件<ctype.h>char*tmp=(char*)&pData[0];_pData.append(1,'+');//添加符号(默认为'+')if((*tmp<'0'||*tmp>'9')&&*tmp!=''&&*tmp!='+'&&*tmp!='-'&&*tmp!='\t')//排除其他符号{//cout<<"false"<<endl;_pData.append(1,'0');_value=0;return;}while(isspace(*tmp))//while(*tmp=='')//消除前面的空格(tab){tmp++;}if(*tmp=='+'||*tmp=='-')//跳过符号/修正符号{if(*tmp=='-'){_pData[0]='-';}tmp++;}while(*tmp=='0')//消除前面的0(必须先消除空格,再消除0,最后判断+(-)){tmp++;}//*********************//一个一个追加效率不高-->转化为一次开辟//while(isdigit(*tmp))//while(*tmp>='0'&&*tmp<='9')//{//_pData.append(1,*tmp++);//}//*********************_pData.resize(strlen(tmp)+1);inti=1;while(isdigit(*tmp)){_pData[i++]=*tmp++;}if(*tmp!='\0'){//cout<<"false"<<endl;_value=0;return;}//若超出INT64表示的范围则用string管理,否则用INT64,string综合管理if(!PDataIsOverINT64()){size_ti=1;_value=0;for(i=1;i<_pData.size();i++){_value=_value*10+_pData[i]-'0';}if(_pData[0]=='-')_value*=-1;}}BigData::~BigData(){}boolBigData::PDataIsOverINT64()const{std::stringtmp("+9223372036854775807");if(_pData[0]=='-'){tmp="-9223372036854775808";}if((_pData.size()<tmp.size())||(_pData.size()==tmp.size()&&_pData<=tmp)){returnfalse;}returntrue;}std::ostream&operator<<(std::ostream&_cout,constBigData&bigdata)//不能在_cout前加const->_cout<<10<<endl;将不能通过{if(!bigdata.PDataIsOverINT64()){_cout<<bigdata._value;}else{char*tmp=(char*)&bigdata._pData[0];if('+'==*tmp){tmp++;}while(*tmp){_cout<<*tmp++;}//_cout<<endl;}return_cout;}voidBigData::Print(){if(!PDataIsOverINT64()){cout<<_value<<endl;//printf("%lld\n",_value);return;}if(*(char*)&_pData[0]=='+'){printf("%s\n",&_pData[1]);return;}printf("%s\n",&_pData[0]);}voidInvert(string&pdata){intleft=1;intright=pdata.size()-1;while(left<right){swap(pdata[left++],pdata[right--]);}}BigDataBigData::operator+(constBigDatabigdata){//1、都在INT64范围内<运算后在范围内,运算后不在范围内>(再进行构造可以解决)//2、都不在INT64范围内<运算后在范围内,运算后不在范围内>//3、一个在一个不在<运算后在范围内,运算后不在范围内>////如果全部用string进行计算,就达不到数值小时用基本类型提高运算的目的//由于实现结构是若在INT64范围内_value与_pData共同管理,若不在只由_pData管理//所以,可以将上面分化成两类<1、都在范围内(<运算后在范围内,运算后不在范围内>)2、至少有一个不在范围内>if(!PDataIsOverINT64()&&!bigdata.PDataIsOverINT64()){if(_pData[0]!=bigdata._pData[0])//若异号,则肯定不会溢出{returnBigData(_value+bigdata._value);}else//同号{if(_pData[0]=='+')//为正{if(_value<=MAX_INT64-bigdata._value)//结果不溢出{returnBigData(_value+bigdata._value);}else//结果溢出{returnBigData(Add(_pData,bigdata._pData));}}else//为负{if(_value>=MIN_INT64-bigdata._value)//结果不溢出{returnBigData(_value+bigdata._value);}else//结果溢出{returnBigData(Add(_pData,bigdata._pData));}}}}else//至少有一个溢出{returnBigData(Add(_pData,bigdata._pData));}}BigDataBigData::operator-(constBigDatabigdata){//1、都在范围内(运算后在范围内,运算后不在范围内)//2、至少有一个不在范围内if(!PDataIsOverINT64()&&!bigdata.PDataIsOverINT64()){//同号相减不可能溢出,异号相减才可能溢出if(_pData[0]==bigdata._pData[0])//同号{returnBigData(_value-bigdata._value);}else//异号{if(_pData[0]=='+')//第一个为正,第二个为负{if(_value<MAX_INT64+bigdata._value)//结果不溢出{returnBigData(_value-bigdata._value);}else//结果溢出{returnSub(_pData,bigdata._pData);}}else//第一个为负,第二个为正{if(_value>MIN_INT64+bigdata._value)//结果不溢出{returnBigData(_value-bigdata._value);}else//结果溢出{returnSub(_pData,bigdata._pData);}}}}else{returnSub(_pData,bigdata._pData);}}void_EachAdd0(string&pdate)//各项添加'0'{intsize=pdate.size();inti=1;for(i=1;i<size;i++){pdate[i]+='0';}}void_EachSub0(string&pdate)//各项去'0'{intsize=pdate.size();inti=1;for(i=1;i<size;i++){pdate[i]-='0';}}BigDataBigData::Add(stringpData1,stringpData2){//转化为string中从低到高字符相加//若同号就相加,若异号,转为减if(pData1[0]!=pData2[0])//异号{if(pData1[0]=='+'){pData2[0]='+';returnSub(pData1,pData2);}else{pData1[0]='+';returnSub(pData2,pData1);}}else//同号{//判断哪个位数多,放在前面if(pData1.size()<pData2.size()){swap(pData1,pData2);}std::stringtmp;intsize1=pData1.size();intsize2=pData2.size();intsizet=size1+1;intflag=0;tmp.resize(size1+1);tmp[0]=pData1[0];for(inti=0;i<size1-1;i++){flag=0;charcur='0';if(size2-1-i>0){cur=pData2[size2-1-i];}tmp[sizet-i-1]=pData1[size1-1-i]+cur-2*'0';//tmp存数值而不是数字字符if(tmp[size1-i]/10==1){flag=1;tmp[size1-i]%=10;}pData1[size1-i-2]+=flag;}tmp[1]=flag;_EachAdd0(tmp);returnBigData(tmp);}}BigDataBigData::Sub(stringpData1,stringpData2){//转化为string中从低到高字符相减//若同号就相减(注意前后位数不同),若异号,转为加if(pData1[0]!=pData2[0])//异号{if(pData1[0]=='+'){pData2[0]='+';returnAdd(pData1,pData2);}else{pData2[0]='-';returnAdd(pData1,pData2);}}else//同号{//取数值的符号,将较大值放在前面if(pData1.size()<pData2.size()||(pData1.size()==pData2.size()&&(strcmp(pData1.c_str(),pData2.c_str())<0))){if(pData1[0]=='+'){pData2[0]='-';}else{pData2[0]='+';}swap(pData1,pData2);}std::stringtmp;intsize1=pData1.size();intsize2=pData2.size();intsizet=size1;intflag=0;tmp.resize(sizet);tmp[0]=pData1[0];for(inti=0;i<size1-1;i++){flag=0;intcur=0;if(i<size2-1){cur=pData1[size1-i-1]-pData2[size2-i-1];}else{cur=pData1[size1-i-1]-'0';}if(cur<0){flag=1;cur+=10;}tmp[sizet-1-i]=cur+'0';pData1[size1-2-i]-=flag;}returnBigData(tmp);}}BigDataBigData::operator*(constBigDatabigdata){//1、都在INT64范围内<运算后在范围内,运算后不在范围内>//同号与MAX_DATA比较异号与MIN_DATA比较//2、至少一个不在范围内if(0==_value||0==bigdata._value){returnBigData(0);}if(!PDataIsOverINT64()&&!bigdata.PDataIsOverINT64()){if(_pData[0]==bigdata._pData[0])//同号{if(_value>=0)//为正{if(_value<MAX_INT64/bigdata._value)//结果在范围内{returnBigData(_value*bigdata._value);}else//结果不在范围内{returnMul(_pData,bigdata._pData);}}else//为负{if(_value>MAX_INT64/bigdata._value)//结果在范围内{returnBigData(_value*bigdata._value);}else//结果不在范围内{returnMul(_pData,bigdata._pData);}}}else//异号{if(_value>=0)//为正负{if(_value<MIN_INT64/bigdata._value)//结果在范围内{returnBigData(_value*bigdata._value);}else//结果不在范围内{returnMul(_pData,bigdata._pData);}}else//为负正{if(_value>MIN_INT64/bigdata._value)//结果在范围内{returnBigData(_value*bigdata._value);}else//结果不在范围内{returnMul(_pData,bigdata._pData);}}}}else{returnMul(_pData,bigdata._pData);}}BigDataBigData::Mul(stringpData1,stringpData2){//同号异号先大数后小数//为提高效率外层循环次数少,内层次数多std::stringtmp;intsize1=pData1.size();intsize2=pData2.size();intsizet=size1+size2;tmp.resize(size1+size2);tmp[0]='+';if(pData1[0]!=pData2[0])//同号异号{tmp[0]='-';}if(size1<size2||(size1==size2&&strcmp(&pData1[0],pData2.c_str())<0))//先大数后小数{swap(pData1,pData2);swap(size1,size2);}_EachSub0(pData1);_EachSub0(pData2);//tmp初始化时全为0for(inti=1;i<size2;i++)//小数位数{if(pData2[size2-i]==0)//若位数上为0则跳过{continue;}for(intj=1;j<size1;j++)//大数位数{if(pData1[size1-j]==0)//若位数上为0则跳过{continue;}tmp[sizet-j-i+1]+=pData1[size1-j]*pData2[size2-i];if(tmp[sizet-j-i+1]>=10){tmp[sizet-j-i]+=tmp[sizet-j-i+1]/10;tmp[sizet-j-i+1]%=10;}}}for(inti=0;i<sizet-1;i++){if(tmp[sizet-i-1]>=10){tmp[sizet-i-2]+=tmp[sizet-i-1]/10;tmp[sizet-i-1]%=10;}}_EachAdd0(tmp);returnBigData(tmp);}BigDataBigData::operator/(constBigDatabigdata){//1、排除除数为0//2、在范围内,不在范围内//3、不在范围内<左(被除数)比右(除数)小为0,左比右大>//4、正负if(0==bigdata._value){assert(false);}if(!PDataIsOverINT64()&&!bigdata.PDataIsOverINT64()){returnBigData(_value/bigdata._value);}else{//左(被除数)比右(除数)小为0if(_pData.size()<bigdata._pData.size()||(_pData.size()==bigdata._pData.size()&&_pData[0]==bigdata._pData[0]&&strcmp((char*)&_pData[0],(char*)&bigdata._pData[0])<0)){returnBigData(0);//正0负0都记为0}else//左比右大{returnDiv(_pData,bigdata._pData);}}}BigDataBigData::Div(stringpData1,stringpData2){//正负且参数左大右小char*_trueDiv(char*tp1,char*tmp2,intsize,string&cur);stringcur;cur.append(1,'+');if(pData1[0]!=pData2[0]){cur[0]='-';}char*tmp1=(char*)malloc(pData1.size());//*tmp2=(char*)malloc(pData2.size());strcpy(tmp1,&pData1[1]);//strcpy内部实现free(tmp1)char*tmp2=&pData2[1];intsize2=strlen(tmp2);intsizermd=size2;intexcursion=size2;char*rmd=NULL;while(strlen(tmp1)>strlen(tmp2)||(strlen(tmp1)==strlen(tmp2)&&strcmp(tmp1,tmp2)>0))//左大于右时,循环{while(sizermd<size2||(sizermd==size2&&strncmp(tmp1,tmp2,sizermd)<0))//不够商0{cur.append(1,'0');sizermd++;++excursion;}rmd=_trueDiv(tmp1,tmp2,sizermd,cur);//1671331071sizermd=strlen(rmd);strcat(rmd,&pData1[++excursion]);tmp1=rmd;sizermd++;//将余数与剩余被除数相接}returnBigData(cur);}char*_trueDiv(char*tp1,char*tp2,intsize1,string&cur){//只有tp1和tp2位数相同且比tp2大,或者比tp2多一位的情况intsize2=strlen(tp2);inti=0;tp1[size1]='\0';charcount=0;intflag=0;while(size1>size2||(size1==size2&&strcmp(tp1,tp2)>0))//tp1大于tp2{for(i=0;i<size1;i++){flag=0;intcount=0;if(i<size2){count=tp1[size1-i-1]-tp2[size2-i-1];}else{count=tp1[size1-i-1]-'0';}if(count<0){flag=1;count+=10;}tp1[size1-1-i]=count+'0';tp1[size1-2-i]-=flag;while(*tp1=='0'&&size1>1)//可能出现整除情况{tp1++;size1--;}}count++;}cur.append(1,count+'0');returntp1;}//<test.cpp>#include"BIGDATA.h"voidtest(){BigDatab0(13215156);BigDatab10(-13215156);BigDatab11(9787687678661325156);//当传入的数值大于MAX_DATA且位数相等时,编译器不能检测,导致由正转负BigDatab12(-9223372036854775807);BigDatab1("a13215jfiow");b1.Print();cout<<b1<<endl;BigDatab2("+000023215");cout<<b2<<endl;b2.Print();BigDatab3("33215jfiow");//(Tab、空格键消除用isspace(int))cout<<b3<<endl;b3.Print();BigDatab4("-33215jfiow");cout<<b4<<endl;b4.Print();BigDatab5("43215jfiow");b5.Print();cout<<b5<<endl;//BigDatab6("4321537537354373783783");//b6.Print();//cout<<b6<<endl;BigDatab7("-43215378338735373783537");cout<<b7<<endl;b7.Print();BigDatab8("-9223372036854775808");cout<<b8<<endl;b8.Print();BigDatab9("-999999");cout<<b9<<endl;b9.Print();BigDatab101("43215378338735373783537");BigDatab102("-43215378338735373783537");BigDatab103("-43215378338735373783537");BigDatab110("-43215378338735373783537");(b2+b9).Print();cout<<(b2+b9)<<endl;}voidtestAdd(){BigDatab1("-45353");BigDatab2("37353753");BigDatab3("-9223372036854775808");BigDatab4("9223372036854775800");BigDatab5("-9223372036854775810");BigDatab6("9223372036854775900");cout<<(b1+b1)<<endl;cout<<(b2+b2)<<endl;cout<<(b1+b2)<<endl;cout<<(b1+b4)<<endl;cout<<b3<<endl;cout<<(b1+b3)<<endl;cout<<(b2+b4)<<endl;cout<<(b2+b5)<<endl;cout<<(b1+b6)<<endl;cout<<(b6+b1)<<endl;}voidtestSub(){BigDatab1("-45353");BigDatab2("37353753");BigDatab3("-9223372036854775808");BigDatab4("9223372036854775800");BigDatab5("-9223372036854775810");BigDatab6("9223372036854775900");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;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;}voidtestMul(){BigDatab1("-45353");BigDatab2("37353753");BigDatab3("-9223372036854775808");BigDatab4("9223372036854775800");BigDatab5("-9223372036854775810");BigDatab6("9223372036854775900");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;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;BigDatab7("-203367738338252");cout<<b7*b1<<endl;}voidtestDiv(){BigDatab1("-45353");BigDatab2("37353753");BigDatab3("-9223372036854775808");BigDatab4("9223372036854775800");BigDatab5("-9223372036854775810");BigDatab6("9223372036854775900");BigDatab7("-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;}intmain(){//testAdd();//testSub();//testMul();testDiv();system("pause");return0;}