【片段集】大数运算
发布时间:2020-12-14 03:26:36 所属栏目:大数据 来源:网络整理
导读:大数就是很大很大的超出64位整数的表示范围的数。 使用竖式进行加减乘除运算,支持任意位数的整数。暂不支持小数。 上代码。 BigNumber.h #pragma once#include iostreamusing namespace std;#define DIGITS_OF_BIG_NUMBER 50class CBigNumber{public://oper
大数就是很大很大的超出64位整数的表示范围的数。 使用竖式进行加减乘除运算,支持任意位数的整数。暂不支持小数。 上代码。 BigNumber.h #pragma once #include <iostream> using namespace std; #define DIGITS_OF_BIG_NUMBER 50 class CBigNumber { public: //operators friend ostream& operator <<(ostream &cout,CBigNumber& bignumber); friend istream& operator >>(istream &cin,CBigNumber& bignumber); friend bool operator >(CBigNumber &bgn1,CBigNumber &bgn2); friend bool operator >=(CBigNumber &bgn1,CBigNumber &bgn2); friend bool operator ==(CBigNumber &bgn1,CBigNumber &bgn2); friend bool operator <(CBigNumber &bgn1,CBigNumber &bgn2); friend bool operator <=(CBigNumber &bgn1,CBigNumber &bgn2); friend CBigNumber& operator +(CBigNumber &bgn1,CBigNumber &bgn2); friend CBigNumber& operator +(int n,CBigNumber &bgn2); friend CBigNumber& operator +(CBigNumber &bgn1,int n); friend CBigNumber& operator -(CBigNumber &bgn1,CBigNumber &bgn2);//没有进行符号处理 friend CBigNumber& operator *(CBigNumber &bgn1,CBigNumber &bgn2); friend CBigNumber& operator /(CBigNumber &bgn1,CBigNumber &bgn2); public: CBigNumber(); CBigNumber(char* number); CBigNumber(int n); CBigNumber(long n); private: char m_cSign;//符号'+' or '-' 【未实现】 int m_Number[DIGITS_OF_BIG_NUMBER];//存储数据,栈式存储 int m_nDigits;//记录位数,由于数据是从高到低存储,初始值为DIGITS_OF_BIG_NUMBER,表示没有数位。 }; ostream& operator <<(ostream &cout,CBigNumber& bignumber); istream& operator >>(istream &cin,CBigNumber& bignumber); bool operator >(CBigNumber &bgn1,CBigNumber &bgn2); bool operator >=(CBigNumber &bgn1,CBigNumber &bgn2); bool operator ==(CBigNumber &bgn1,CBigNumber &bgn2); bool operator <(CBigNumber &bgn1,CBigNumber &bgn2); bool operator <=(CBigNumber &bgn1,CBigNumber &bgn2); CBigNumber& operator +(CBigNumber &bgn1,CBigNumber &bgn2); CBigNumber& operator +(int n,CBigNumber &bgn2); CBigNumber& operator +(CBigNumber &bgn1,int n); CBigNumber& operator -(CBigNumber &bgn1,CBigNumber &bgn2); CBigNumber& operator *(CBigNumber &bgn1,CBigNumber &bgn2);//bgn1为被乘数,bgn2为乘数 CBigNumber& operator /(CBigNumber &bgn1,CBigNumber &bgn2);////bgn1为被除数,bgn2为除数 BigNumber.cpp #include <iostream> #include "BigNumber.h" using namespace std; CBigNumber::CBigNumber() { m_cSign='+'; m_nDigits=DIGITS_OF_BIG_NUMBER; memset(m_Number,DIGITS_OF_BIG_NUMBER*4); } CBigNumber::CBigNumber(char* number) { m_nDigits=DIGITS_OF_BIG_NUMBER; memset(m_Number,DIGITS_OF_BIG_NUMBER*4); char c=*number; if(c!='-') m_cSign='+';//如果以'-'开头就认为是负数,否则都认为是正数 else m_cSign='-'; while(c!=' ') { if(c>='0'&&c<='9') { m_nDigits--; m_Number[m_nDigits]=c-'0'; if(m_nDigits==0) break; } number++; c=*number; } //翻转成从低到高的阅读顺序 int d=(DIGITS_OF_BIG_NUMBER-1-m_nDigits)/2; for(int i=0;i<=d;i++) { char c=m_Number[m_nDigits+i]; m_Number[m_nDigits+i]=m_Number[DIGITS_OF_BIG_NUMBER-1-i]; m_Number[DIGITS_OF_BIG_NUMBER-1-i]=c; } } CBigNumber::CBigNumber(long n) { m_nDigits=DIGITS_OF_BIG_NUMBER; memset(m_Number,DIGITS_OF_BIG_NUMBER*4); while(n>0)//n=0时不用操作,因为BigNumber初始化就是0 { m_nDigits--; m_Number[m_nDigits]=n%10; n=n/10; } } CBigNumber::CBigNumber(int n) { m_nDigits=DIGITS_OF_BIG_NUMBER; memset(m_Number,DIGITS_OF_BIG_NUMBER*4); while(n>0)//n=0时不用操作,因为BigNumber初始化就是0 { m_nDigits--; m_Number[m_nDigits]=n%10; n=n/10; } } ostream& operator <<(ostream& cout,CBigNumber &bignumber) { if(bignumber.m_nDigits==DIGITS_OF_BIG_NUMBER) cout<<0; for(int i=bignumber.m_nDigits;i<DIGITS_OF_BIG_NUMBER;i++) cout<<bignumber.m_Number[i]; return cout; } istream& operator >>(istream &cin,CBigNumber &bignumber) { char c; c=getchar(); while(c>='0'||c<=9) { bignumber.m_nDigits--; bignumber.m_Number[bignumber.m_nDigits]=c-'0'; c=getchar(); if(bignumber.m_nDigits==0) break; } return cin; } bool operator >(CBigNumber &bgn1,CBigNumber &bgn2) { if(bgn1.m_nDigits<bgn2.m_nDigits)//bgn1的位数多 return true; else if(bgn1.m_nDigits>bgn2.m_nDigits)//bgn1的位数少 return false; for(int i=bgn1.m_nDigits;i<DIGITS_OF_BIG_NUMBER;i++)//二者位数相同 { if(bgn1.m_Number[i]>bgn2.m_Number[i])// { return true; } else if(bgn1.m_Number[i]<bgn2.m_Number[i]) { return false; } } //执行到这里说明是等于 return false; } bool operator >=(CBigNumber &bgn1,CBigNumber &bgn2) { if(bgn1.m_nDigits<bgn2.m_nDigits)//bgn1的位数多 return true; else if(bgn1.m_nDigits>bgn2.m_nDigits)//bgn1的位数少 return false; for(int i=bgn1.m_nDigits;i<DIGITS_OF_BIG_NUMBER;i++)//二者位数相同 { if(bgn1.m_Number[i]>bgn2.m_Number[i])// { return true; } else if(bgn1.m_Number[i]<bgn2.m_Number[i]) { return false; } } //执行到这里说明是等于 return true; } bool operator ==(CBigNumber &bgn1,CBigNumber &bgn2) { if(bgn1.m_nDigits!=bgn2.m_nDigits)//二者位数不相同 return false; for(int i=bgn1.m_nDigits;i<DIGITS_OF_BIG_NUMBER;i++)//二者位数相同 { if(bgn1.m_Number[i]!=bgn2.m_Number[i]) { return false; } } //执行到这里说明是等于 return true; } bool operator <(CBigNumber &bgn1,CBigNumber &bgn2) { if(bgn1.m_nDigits<bgn2.m_nDigits)//bgn1的位数多 return false; else if(bgn1.m_nDigits>bgn2.m_nDigits)//bgn1的位数少 return true; for(int i=bgn1.m_nDigits;i<DIGITS_OF_BIG_NUMBER;i++)//二者位数相同 { if(bgn1.m_Number[i]<bgn2.m_Number[i])// { return true; } else if(bgn1.m_Number[i]>bgn2.m_Number[i]) { return false; } } //执行到这里说明是等于 return false; } bool operator <=(CBigNumber &bgn1,CBigNumber &bgn2) { if(bgn1.m_nDigits<bgn2.m_nDigits)//bgn1的位数多 return false; else if(bgn1.m_nDigits>bgn2.m_nDigits)//bgn1的位数少 return true; for(int i=bgn1.m_nDigits;i<DIGITS_OF_BIG_NUMBER;i++)//二者位数相同 { if(bgn1.m_Number[i]<bgn2.m_Number[i])// { return true; } else if(bgn1.m_Number[i]>bgn2.m_Number[i]) { return false; } } //执行到这里说明是等于 return true; } CBigNumber& operator +(CBigNumber &bgn1,CBigNumber &bgn2) { static CBigNumber bgnSum;//较大的数作为被加数,和放在较大的数里 static CBigNumber *pBgnAddend;//较小的数作为加数 if(bgn1.m_nDigits<bgn2.m_nDigits) { bgnSum=bgn1; pBgnAddend=&bgn2; } else { bgnSum=bgn2; pBgnAddend=&bgn1; } int carry=0; for(int i=DIGITS_OF_BIG_NUMBER-1;i>=bgnSum.m_nDigits;i--) { carry+=bgnSum.m_Number[i]+pBgnAddend->m_Number[i]; if(carry>=10)//如果大于10的话向前进位 { bgnSum.m_Number[i]=carry-10; carry=1; } else { bgnSum.m_Number[i]=carry; carry=0; } if(carry==0&&pBgnAddend->m_nDigits>=i)//加数加完了且没有进位就结束加法 break; } //bgnSum.m_nDigits=t; if(carry&&bgnSum.m_nDigits>0)//加完了还有进位且不会溢出(被加数加完了),就补上 { bgnSum.m_nDigits--; bgnSum.m_Number[bgnSum.m_nDigits]=1; } return bgnSum; } CBigNumber& operator +(int n,CBigNumber &bgn2) { CBigNumber bgn1(n); return bgn1+bgn2; } CBigNumber& operator +(CBigNumber &bgn1,int n) { CBigNumber bgn2(n); return bgn1+bgn2; } CBigNumber& operator -(CBigNumber &bgn1,CBigNumber &bgn2) { static CBigNumber bgnDif;//较大的数作为被减数,差放在被减数中 static CBigNumber *pBgnSubtractor;//较小的数作为减数 if(bgn1>bgn2) { bgnDif=bgn1; pBgnSubtractor=&bgn2; } else { bgnDif=bgn2; pBgnSubtractor=&bgn1; } int carry=0; for(int i=DIGITS_OF_BIG_NUMBER-1;i>=bgnDif.m_nDigits;i--) { bgnDif.m_Number[i]-=carry; carry=0; if(bgnDif.m_Number[i]<pBgnSubtractor->m_Number[i]) { carry=1; bgnDif.m_Number[i]=bgnDif.m_Number[i]+10-pBgnSubtractor->m_Number[i]; } else { bgnDif.m_Number[i]=bgnDif.m_Number[i]-pBgnSubtractor->m_Number[i]; } if(carry==0&&pBgnSubtractor->m_nDigits>=i)//如果进位为0且减数减完了就结束 break; } //被减数减到头了还没减完,这种情况不存在 carry=0; while(!bgnDif.m_Number[carry]) carry++;//重新计算位数 bgnDif.m_nDigits=carry; return bgnDif; } CBigNumber& operator *(CBigNumber &bgn1,CBigNumber &bgn2) { static CBigNumber bgnProduct;//积放在这里面 static CBigNumber *pBgn; memset(&bgnProduct,sizeof(CBigNumber)); int carry=0; int i,j; for(i=DIGITS_OF_BIG_NUMBER-1;i>=bgn2.m_nDigits;i--)//乘数去成被乘数,循环的次数是乘数的位数 { carry=0; for(j=DIGITS_OF_BIG_NUMBER-1;j>=bgn1.m_nDigits;j--)//乘以被乘数的每一位 { carry=bgn2.m_Number[i]*bgn1.m_Number[j]+carry+bgnProduct.m_Number[j-(DIGITS_OF_BIG_NUMBER-1-i)]; if(carry>=10) { bgnProduct.m_Number[j-(DIGITS_OF_BIG_NUMBER-1-i)]+=carry%10; carry/=10; } else { bgnProduct.m_Number[j-(DIGITS_OF_BIG_NUMBER-1-i)]=carry; carry=0; } } if(carry!=0)//被乘数乘空了还有进位 { bgnProduct.m_Number[j-(DIGITS_OF_BIG_NUMBER-1-i)]=carry; } } i=0; while(bgnProduct.m_Number[i]==0) i++; bgnProduct.m_nDigits=i; return bgnProduct; } CBigNumber& operator /(CBigNumber &bgn1,CBigNumber &bgn2) { static CBigNumber bgnQuotient;//商 static CBigNumber bgnTemp;//除法的中间量 memset(&bgnQuotient,sizeof(CBigNumber)); memset(&bgnTemp,sizeof(CBigNumber)); bgnQuotient.m_nDigits=DIGITS_OF_BIG_NUMBER; if(bgn1<bgn2)//小于的话结果为0 return bgnQuotient; int nIndex=bgn1.m_nDigits-1;//当前取到除数的第几位,指向上一次读的位置 //取被除数的前n个数放进temp,n为除数的位数 for(int i=DIGITS_OF_BIG_NUMBER-bgn2.m_nDigits;i>0;i--) { nIndex++; bgnTemp.m_Number[DIGITS_OF_BIG_NUMBER-i]=bgn1.m_Number[nIndex]; } bgnTemp.m_nDigits=bgn2.m_nDigits; //cout<<bgnTemp<<endl; bgnQuotient.m_nDigits=0; while(nIndex<DIGITS_OF_BIG_NUMBER-1)//被除数的所有位都取完结束运算 { //如果temp小于除数,再取一个数放进去 while(bgnTemp<bgn2&&nIndex<DIGITS_OF_BIG_NUMBER-1) { for(int i=bgnTemp.m_nDigits;i<DIGITS_OF_BIG_NUMBER;i++)//temp中数据左移 bgnTemp.m_Number[i-1]=bgnTemp.m_Number[i]; bgnTemp.m_nDigits--; nIndex++; bgnTemp.m_Number[DIGITS_OF_BIG_NUMBER-1]=bgn1.m_Number[nIndex]; bgnQuotient.m_nDigits++;//准备迎接下一个商,如果是继续去数放进temp,那么商中会增加一个0 } //计算temp/除数的结果,以及余数放进temp while(bgnTemp>=bgn2) { bgnQuotient.m_Number[bgnQuotient.m_nDigits]++; bgnTemp=bgnTemp-bgn2; //cout<<"/.."<<bgnTemp<<"t"<<bgnQuotient.m_Number[bgnQuotient.m_nDigits]<<endl; } } //左移 for(int i=bgnQuotient.m_nDigits;i>=0;i--) { bgnQuotient.m_Number[DIGITS_OF_BIG_NUMBER-1-bgnQuotient.m_nDigits+i]=bgnQuotient.m_Number[i]; } bgnQuotient.m_nDigits=DIGITS_OF_BIG_NUMBER-1-bgnQuotient.m_nDigits; return bgnQuotient; } main.cpp #include <iostream> #include "BigNumber.h" using namespace std; int main(int argc,char* argv[]) { CBigNumber bignumber1("123456789123456789"); CBigNumber bignumber2("123456789123456780"); cout<<"条件运算:"<<endl; cout<<"> "<<(bignumber1>bignumber2)<<endl; cout<<">="<<(bignumber1>=bignumber2)<<endl; cout<<"=="<<(bignumber1==bignumber2)<<endl; cout<<"< "<<(bignumber1<bignumber2)<<endl; cout<<"<="<<(bignumber1<=bignumber2)<<endl; cout<<"n四则运算:"<<endl; cout<<"+"<<bignumber1+bignumber2<<endl; cout<<"-"<<bignumber1-bignumber2<<endl; //cout<<"*"<<bignumber1*bignumber2<<endl; cout<<"*"<<CBigNumber("123456789")*CBigNumber("123456789")<<endl; cout<<"/"<<CBigNumber("78945613")/CBigNumber("123")<<endl; CBigNumber bgnI("1"),bgnJ("1");double n=1,m=1; cout<<1<<'t'<<bgnI<<"ttt"<<n<<endl; cout<<2<<'t'<<bgnI<<"ttt"<<endl; for(int i=2;i<200;i+=2) { bgnI=bgnI+bgnJ; n=m+n; bgnJ=bgnI+bgnJ; m=m+n; cout<<i<<'t'<<bgnI<<"ttt"<<n<<endl; cout<<i+1<<'t'<<bgnJ<<"ttt"<<m<<endl; } return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |