东莞公众号开发公司,想找搜索引擎优化,电商主图制作软件,网站开发模板word1.问题#xff1a;大数计算可能超出数据类型范围
当单独计算 #xff0c;因为 #xff0c;double的最大取值为1.79769e308#xff0c;所以 肯定超过了double的表示范围。
同样#xff0c;对于300#xff01;也是如此。
那我们应该怎么去计算和存储结果呢#xff1f;…1.问题大数计算可能超出数据类型范围
当单独计算 因为 double的最大取值为1.79769e308所以 肯定超过了double的表示范围。
同样对于300也是如此。
那我们应该怎么去计算和存储结果呢
2.解决方案
从数学角度出发对于超级大的数运算方式、运算规律等肯定保持不变的。
很多时候我们主要是利用相关的定理、公式进行简化或者极限处理。
由于我项目里的精度要求就 e-10于是可以采用相对宽松的方式解决这个问题
科学计数法
3.代码实现
#ifndef __BigNumeric_h
#define __BigNumeric_h
#include cmathtemplatetypename _T
class BigNumeric
{
private:_T mantissa; //基数int exponent; //指数public:BigNumeric(_T num){if (num 0) {exponent 0;mantissa 0;}else{exponent std::floor(std::log10(std::abs(num)));mantissa num / std::pow(10, exponent);}}~BigNumeric(){}BigNumeric(const BigNumeric other){if (this other) return;this-exponent other.exponent;this-mantissa other.mantissa;}BigNumeric operator(const BigNumeric other){/*if(this other) return *this;*/this-exponent other.exponent;this-mantissa other.mantissa;return *this;}public:_T value(){if (this-exponent 308) return 0.0;return this-mantissa * std::pow(10.0, this-exponent);}//乘法BigNumeric operator*(const BigNumeric opr){BigNumeric_T resmnt(this-mantissa * opr.mantissa);this-exponent resmnt.exponent this-exponent opr.exponent;this-mantissa resmnt.mantissa;return *this;}BigNumeric operator*(const _T opr){BigNumeric_T oprbgn(opr);*this *this * oprbgn;return *this;}friend BigNumeric operator*(const _T opr1, BigNumeric opr2){return opr2 * opr1;}//除法BigNumeric operator/(const BigNumeric opr){BigNumeric_T resmnt(this-mantissa / opr.mantissa);this-exponent resmnt.exponent this-exponent - opr.exponent;this-mantissa resmnt.mantissa;return *this;}BigNumeric operator/(const _T opr){BigNumeric_T oprbgn(opr);*this *this / oprbgn;return *this;}friend BigNumeric operator/(const _T opr, const BigNumeric opr1){BigNumeric_T oprbgn(opr);return oprbgn / opr1;}//加法BigNumeric operator(const BigNumeric opr){if (this-exponent - opr.exponent 15) return *this;else if (this-exponent - opr.exponent -15){*this opr;return *this;} int min this-exponent opr.exponent ? opr.exponent : this-exponent;BigNumeric_T resmnt(this-mantissa * std::pow(10.0, this-exponent - min) opr.mantissa * std::pow(10.0, opr.exponent - min));this-exponent resmnt.exponent min;this-mantissa resmnt.mantissa;return *this;}BigNumeric operator(const _T opr){BigNumeric_T oprbgn(opr);*this *this oprbgn;return *this;}friend BigNumeric operator(const _T opr1, BigNumeric opr2){return opr2 opr1;}//减法BigNumeric operator-(const BigNumeric opr){BigNumeric temp(opr);*this *this temp * (-1.0);return *this;}BigNumeric operator-(const _T opr){BigNumeric oprbgn(opr);*this *this - oprbgn;return *this;}friend BigNumeric operator-(const _T opr1, BigNumeric opr2){return opr2 - opr1;}//开方BigNumeric Sqrt(){_T bgnmant std::sqrt(this-mantissa);int bgnexp this-exponent;if (bgnexp % 2 0){this-mantissa bgnmant;this-exponent bgnexp / 2;}else{BigNumeric temp(bgnmant * std::sqrt(10.0));this-mantissa temp.mantissa;this-exponent temp.exponent bgnexp / 2;}return *this;}//幂BigNumeric Pow(_T exp){BigNumeric temp(Vpow(this-mantissa, exp));this-mantissa temp.mantissa;this-exponent temp.exponent this-exponent * exp;return *this;}public:static BigNumeric Factorial(int opr){if (opr 0) return 1.0 / Factorial(-1.0 * opr 1);else if (opr 0) return BigNumeric(1.0);return Factorial(opr - 1) * opr;}static BigNumeric Epow(_T exp){BigNumeric res(1.0);double e 2.71828182845904523536;if (std::abs(exp) 700) return BigNumeric(std::pow(e, exp));int count exp / 700;BigNumeric bgn(std::pow(e, 700.0));for (size_t i 0; i count; i)res res * bgn;BigNumeric bgn1(std::pow(e, exp - count * 700));res res * bgn1;return res;}static BigNumeric Vpow(_T e, _T exp){BigNumeric res(1.0);BigNumeric bgnmant(e);int chk bgnmant.exponent 0 ? std::abs(exp) : std::abs(exp) * bgnmant.exponent;if (chk 300) return BigNumeric(std::pow(e, exp));int count exp / 300;BigNumeric bgn(std::pow(e, 300.0));for (size_t i 0; i count; i)res res * bgn;BigNumeric bgn1(std::pow(e, exp - count * 300));res res * bgn1;return res;}};#endif // !__BigNumeric_h
4.测试
//测试
#include BigNumeric.hppint main() {BigNumericdouble bignum BigNumericdouble::Factorial(300);BigNumericdouble bignum1 BigNumericdouble::Epow(1000);bignum bignum1 / bignum;return 0;
}
结果6.4369310844548986e-181数字部分精度为 e-12指数部分完全准确。