c++高精度类
頭文件 - intx.h
//intx.h #ifndef INTX_H_ #define INTX_H_ #include <iostream> #include <cstring> #include <string> class intx { private:bool sign;int *num;int len;static int process_char(const char *s,bool &sign,int *&num);static bool unsign_gt(const int *a,const int lena,const int *b,const int lenb);static bool unsign_gte(const int *a,const int lena,const int *b,const int lenb);static int unsign_plus(const int *a,int lena,const int *b,int lenb,int *&result);static int unsign_minus(const int *a,int lena,const int *b,int lenb,int *&result);static int multiply_base(const int *a,const int lena,int n,int *&result);static int unsgin_multiply(const int *a,const int lena,const int *b,const int lenb,int *&result);static bool divide_gte(const int *a,int end,const int *b,int lenb);static int unsign_divide(const int *a,const int lena,const int *b,const int lenb,int *&result);static int unsign_mod(const int *a,const int lena,const int*b,const int lenb,int *&result); public: //constructorintx();intx(const char * s);intx(const std::string & str);intx(int n);intx(const intx &b); //destructor~intx(); //calcbool operator==(const intx &b) const;bool operator>(const intx &b) const;bool operator>=(const intx &b) const;bool operator<(const intx &b) const;bool operator<=(const intx &b) const;intx operator-()const;intx operator+(const intx &b) const;intx operator-(const intx &b) const;intx operator*(const intx &b) const;intx operator/(const intx &b) const;intx operator%(const intx &b) const; //othersfriend std::ostream& operator<<(std::ostream &os,const intx &a);friend std::istream& operator>>(std::istream &is,intx &a);int& operator[](const int sub) const;intx& operator=(const intx &b);intx& operator=(const char *s);intx& operator=(const std::string &str);int size(){return len;}bool IsNatural()const{return sign;} }; #endif實(shí)現(xiàn)文件 - intx.cpp
//intx.cpp #include "intx.h"//private int intx::process_char(const char *s,bool &sign,int *&num) {int len = strlen(s);if(!len)//len == 0{sign = true;num = new int[1];num[0] = 0;len = 1;}elseswitch(s[0]){case '+':sign = true;--len;num = new int[len];for(int i = 0;i < len;++i)num[i] = s[i + 1] - '0';break;case '-':sign = false;--len;num = new int[len];for(int i = 0;i < len;++i)num[i] = s[i + 1] - '0';break;default:sign = true;num = new int[len];for(int i = 0;i < len;++i)num[i] = s[i] - '0';break;}return len; } bool intx::unsign_gt(const int *a,const int lena,const int *b,const int lenb) {if(lena < lenb)return false;else if(lena > lenb)return true;else{for(int i = 0;i < lena;++i)if(a[i] < b[i])return false;else if(a[i] > b[i])return true;return false;} } bool intx::unsign_gte(const int *a,const int lena,const int *b,const int lenb) {if(lena < lenb)return false;else if(lena > lenb)return true;else{for(int i = 0;i < lena;++i)if(a[i] < b[i])return false;else if(a[i] > b[i])return true;return true;} } int intx::unsign_plus(const int *a,int lena,const int *b,int lenb,int *&result) {int rem;if(lenb > lena){const int *temp = a;a = b;b = temp;rem = lena;lena = lenb;lenb = rem;}int len = lena + 1;result = new int[len];int sub = lena;rem = 0;--lena;--lenb;while(lenb >= 0){rem += a[lena--] + b[lenb--];result[sub--] = rem % 10;rem /= 10;}while(lena >= 0){rem += a[lena--];result[sub--] = rem %10;rem /= 10;}if(rem > 0){result[sub] = rem;}else{--len;int *p = new int[len];memcpy(p,result + 1,sizeof(int)*len);delete[] result;result = p;}return len; } int intx::unsign_minus(const int *a,int lena,const int *b,int lenb,int *&result)//a must > b {int len = lena;result = new int[len];memcpy(result,a,sizeof(int)*len);//const int *a can't modify--lenb;--lena;while(lenb >= 0){if(a[lena] >= b[lenb])result[lena] -= b[lenb];else{result[lena] += 10 - b[lenb];--result[lena -1];}--lena;--lenb;}while(lena>=0){if(result[lena] < 0){result[lena] += 10;--result[lena - 1];--lena;}elsebreak;}int zero = 0;while(zero < len)if(result[zero] == 0)++zero;elsebreak;if(zero == len){delete[] result;result = new int[1]{0};len = 1;}else if(zero != 0){len -= zero;int *p = new int[len];memcpy(p,result + zero,sizeof(int)*len);delete[] result;result = p;}return len; } bool intx::divide_gte(const int *a,const int end,const int *b,const int lenb) {int begin = 0;while(a[begin] == 0){++begin;}if(end - begin + 1 < lenb)return false;else if(end - begin + 1 > lenb)return true;else{for(int i = 0;i < lenb;++begin,++i)if(a[begin] > b[i])return true;else if(a[begin] < b[i])return false;return true;} } int intx::multiply_base(const int *a,int lena,const int n,int * &result)//the first may be 0 {int len = lena + 1;result = new int[len];int rem = 0;int sub = lena;--lena;while(lena >= 0){rem += n * a[lena];result[sub] = rem % 10;rem /= 10;--lena;--sub;}if(rem > 0)result[sub] = rem;elseresult[sub] = 0;return len; } int intx::unsgin_multiply(const int *a,const int lena,const int *b,const int lenb,int *&result)//a on the top {int len = lena + lenb;result = new int[len]{0};int *MultiplyTemp;int MultiplyBit = lenb - 1;//the subscript of number in the b to be multipliedwhile(MultiplyBit >= 0){int MultiplyTempSub = multiply_base(a,lena,b[MultiplyBit],MultiplyTemp);//plusint rem = 0;int sub = len - (lenb - MultiplyBit);//the bit when result begin plus--MultiplyTempSub;while(MultiplyTempSub >= 0){rem += result[sub] + MultiplyTemp[MultiplyTempSub];result[sub] = rem % 10;rem /= 10;--sub;--MultiplyTempSub;}if(rem > 0)result[sub] += rem;--MultiplyBit;delete[] MultiplyTemp;}int zero = 0;while(zero < len)if(result[zero] == 0)++zero;elsebreak;if(zero == len){delete[] result;result = new int[1]{0};return 1;}else if(zero != 0){len -= zero;int *p = new int[len];memcpy(p,result + zero,sizeof(int)*len);delete[] result;result = p;} return len; } int intx::unsign_divide(const int *a,const int lena,const int *b,const int lenb,int *&result) {if(lena < lenb){result = new int[1]{0};return 1;}//Judge the first bitint CurrentBit = lenb - 1;//the current number on the consultint len;if(!divide_gte(a,CurrentBit,b,lenb))if(CurrentBit + 1== lena)//lena == lenb && a < b{result = new int[1]{0};return 1;}else{++CurrentBit;len = lena - lenb;result = new int[len];}else{len = lena - lenb + 1;result = new int[len];}//copyint *A = new int[lena];memcpy(A,a,sizeof(int)*lena);int sub = 0;//sub = CurrentBit - (lena - lenb),too much calcwhile(CurrentBit < lena){result[sub] = 0;do{//minusint Asub = CurrentBit;for(int i = lenb - 1;i >= 0;--Asub,--i)if(A[Asub] >= b[i])A[Asub] -= b[i];else{A[Asub] += 10 - b[i];--A[Asub - 1];}while(Asub >= 0)if(A[Asub] < 0){A[sub] += 10;--A[Asub - 1];--Asub;}elsebreak;++result[sub];}while(divide_gte(A,CurrentBit,b,lenb));if(++sub,++CurrentBit == lena)break;while(!divide_gte(A,CurrentBit,b,lenb)){result[sub] = 0;if(++sub,++CurrentBit == lena)break;}}delete[]A;return len; } int intx::unsign_mod(const int *a,const int lena,const int *b,const int lenb,int *&result) {int len = lena;result = new int[len];memcpy(result,a,sizeof(int)*len);if(lena < lenb)return len;//Judge the first bitint CurrentBit = lenb - 1;//the current number on the consultif(!divide_gte(result,CurrentBit,b,lenb)){if(CurrentBit + 1== len)//lena == lenb && a < breturn len;else++CurrentBit;}while(CurrentBit < len){do{//minusint sub = CurrentBit;for(int i = lenb - 1;i >= 0;--sub,--i)if(result[sub] >= b[i])result[sub] -= b[i];else{result[sub] += 10 - b[i];--result[sub - 1];}while(sub >= 0)if(result[sub] < 0){result[sub] += 10;--result[sub - 1];--sub;}elsebreak;}while(divide_gte(result,CurrentBit,b,lenb));while(++CurrentBit != len)if(divide_gte(result,CurrentBit,b,lenb))break;}int zero = 0;while(zero < len)if(result[zero] == 0)++zero;elsebreak;if(zero == len){delete[] result;result = new int[1]{0};len = 1;}else if(zero != 0){len -= zero;int *p = new int[len];memcpy(p,result + zero,sizeof(int)*len);delete[] result;result = p;}return len; } //constructor intx::intx() {sign = true;num = new int[1];num[0] = 0;len = 1; } intx::intx(const char *s) {len = process_char(s,sign,num); } intx::intx(const std::string &str) {const char *s = str.data();new (this)intx(s); } intx::intx(int n) {if(n < 0)sign = false;elsesign = true;if(n == 0){len = 1;num = new int[1]{0};return;}len = 0;int N = n;while(n > 0){n /= 10;++len;}num = new int[len];for(int i = len;i > 0;--i){num[i - 1] = N % 10;N /= 10;} } intx::intx(const intx &b) {sign = b.sign;len = b.len;num = new int[len];memcpy(num,b.num,sizeof(int) * len); } //destructor intx::~intx() {delete[] num; }//calc bool intx::operator==(const intx &b) const {if(len != b.len)return false;else if(sign != b.sign)return false;else{for(int i = 0;i < len;++i)if(num[i] != b.num[i])return false;return true;} } bool intx::operator>(const intx &b) const {if(sign)if(b.sign)return unsign_gt(num,len,b.num,b.len);elsereturn true;elseif(b.sign)return false;elsereturn !unsign_gt(num,len,b.num,b.len); } bool intx::operator>=(const intx &b)const {if(sign)if(b.sign)return unsign_gte(num,len,b.num,b.len);elsereturn true;elseif(b.sign)return false;elsereturn !unsign_gte(num,len,b.num,b.len); } bool intx::operator<(const intx &b) const {return !(*this >= b); } bool intx::operator<=(const intx &b) const {return !(*this > b); } intx intx::operator-()const {intx b = *this;b.sign = !b.sign;return b; } intx intx::operator+(const intx &b) const {intx sum;delete[] sum.num;if(sign)//a >= 0if(b.sign)//a > 0 && b > 0{sum.sign = true;sum.len = unsign_plus(num,len,b.num,b.len,sum.num);}else if(unsign_gte(num,len,b.num,b.len))// a > 0,b < 0,|a| >= |b|{sum.sign = true;sum.len = unsign_minus(num,len,b.num,b.len,sum.num);}else// a > 0,b < 0,|a| < |b|{sum.sign = false;sum.len = unsign_minus(b.num,b.len,num,len,sum.num);}else//a < 0{if(!b.sign)// a < 0, b < 0{sum.sign = false;sum.len = unsign_plus(num,len,b.num,b.len,sum.num);}else if(unsign_gte(b.num,b.len,num,len))// a < 0,b > 0,|a| <= |b|{sum.sign = true;sum.len = unsign_minus(b.num,b.len,num,len,sum.num);}else//a < 0 b > 0 , |a| > |b|{sum.sign = false;sum.len = unsign_minus(num,len,b.num,b.len,sum.num);}}return sum; } intx intx::operator-(const intx &b)const {return *this + (-b); } intx intx::operator*(const intx &b)const {intx product;if(sign == b.sign)product.sign = true;elseproduct.sign = false;delete[] product.num;product.len = unsgin_multiply(num,len,b.num,b.len,product.num);return product; } intx intx::operator/(const intx &b) const {intx consult;if(sign == b.sign)consult.sign = true;elseconsult.sign = false;delete[] consult.num;consult.len = unsign_divide(num,len,b.num,b.len,consult.num);if(consult[0] == 0)//avoid "-0"consult.sign = true;return consult; } intx intx::operator%(const intx &b)const {intx modulo;delete[] modulo.num;modulo.sign = sign;modulo.len = unsign_mod(num,len,b.num,b.len,modulo.num);return modulo; } //others std::ostream& operator<<(std::ostream &os,const intx &a) {if(!a.sign)os << '-';for(int i = 0;i < a.len;++i)os << a.num[i];return os; } std::istream& operator>>(std::istream &is,intx &a) {delete[] a.num;int max = 16;a.num = new int[max];//Judge signchar c;a.len = 0;c = getchar();if(c == '-')a.sign = false;else if(c == '+')a.sign = true;else if(c <= '9' && c >= '1')//the first num{a.num[a.len] = c - '0';++a.len;}else{a.sign = true;a.num[a.len] = 0;++a.len;return is;}//makesure the first bit is inputedif(a.len == 0){c = getchar();if(c >= '1' && c <= '9'){a.num[a.len] = c - '0';++a.len;}else{a.sign = true;a.num[a.len] = 0;++a.len;return is;}}while(c = is.peek(),c >= '0' && c <= '9'){is >> c;a.num[a.len] = c - '0';if(++a.len == max){max *= 2;int *temp = new int[max];memcpy(temp,a.num,sizeof(int)*a.len);delete[] a.num;a.num = temp;}}return is; } int & intx::operator[](const int sub) const {return num[len - 1 - sub]; } intx& intx::operator=(const intx &b) {if(this == &b)return *this;else{len = b.len;sign = b.sign;delete[] num;num = new int[len];memcpy(num,b.num,sizeof(int) * len);return *this;} } intx& intx::operator=(const char *s) {delete[] num;len = process_char(s,sign,num);return *this; } intx& intx::operator=(const std::string &str) {delete[] num;len = process_char(str.data(),sign,num);return *this; }轉(zhuǎn)載于:https://www.cnblogs.com/h-hg/p/8366142.html
總結(jié)
- 上一篇: PokeCats开发者日志(二)
- 下一篇: s3c2440移植MQTT