浮点高精度
1.并查集模板2.求质因数模板3.二分图最大匹配模板(匈牙利算法)4.欧拉函数模板5.ST表模板6.快速幂模板7.字典树模板8.矩阵模板9.Dijkstra单源最短路模板10.最近公共祖先模板(LCA)11.拓扑排序模板12.区间素数筛模板13.Kruskal和Prim模板14.树状数组模板15.二维坐标离散化模板16.单点修改区间查最值-树状数组模板17.KMP模板18.二叉搜索树模板19.DIjkstra进阶模板 路径记录 按权重(结点数最小等)记录20.判断负环模板21.Exgcd 模板22.压位高精度模板23.线段树模板24.扫描线模板25.莫队模板26.带修莫队模板27.SCC缩点模板28.取模+组合数29.FFT 高精度乘法模板30.字符串自然溢出哈希/单哈希/双哈希模板31.树模板32.dsu on tree 模板33.线段树模板重制34.主席树模板35.大数质因数分解模板36.线段树合并模板37.int128输入输出流38.Meissel_Lehmer模板
39.浮点高精度
40.自适应辛普森法41.unordered_map随机底数种子简单封装了一下浮点加法乘法,未验证
struct BigFloat { static const int N = 100, n = 16; //位数,保留位数 vector<int> integer;//整数部分(逆序存储)123. -->321. vector<int> decimal;//小数部分(正序存储).456 -->.456 int integerSize;//整数长度 int decimalSize;//小数长度 BigFloat() { init(); } BigFloat(const string& s) { init(); *this = s; } BigFloat(const double& val) { init(); *this = val; } void init() { integer.reserve(N); decimal.reserve(N); integer.resize(N); decimal.resize(N); integerSize = 0; decimalSize = 0; } BigFloat operator = (const double& value) { (*this).init(); ostringstream oss; oss << fixed << setprecision(n) << value;//保留精度 *this = oss.str(); return *this; } BigFloat operator = (const string &s) { (*this).init(); int idx; for (idx = 0; s[idx] != '.'; idx ++); //定位小数点下标 int len = (int)s.size(); for (int i = idx + 1 ; i < len ; i++) { //正序存储小数部分 decimal[decimalSize++] = s[i] - '0'; } for (int j = idx - 1; j >= 0 ; j--) { //逆序存储整数部分 integer[integerSize++] = s[j] - '0'; } return *this; } BigFloat operator + (const BigFloat &a) { //重载加法运算符 BigFloat ret;//保存返回结果 int qLen = decimalSize > a.decimalSize ? decimalSize : a.decimalSize;//小数长度 int carry = 0;//保存进位,以及小数到整数部分的进位 ret.decimalSize = qLen; for (int i = qLen - 1 ; i >= 0 ; i--) { //小数部分相加 int tmp = decimal[i] + a.decimal[i] + carry; ret.decimal[--qLen] = tmp % 10; //保存结果 carry = tmp / 10; //更新进位 } int pLen = integerSize > a.integerSize ? integerSize : a.integerSize;//整数长度 for (int j = 0 ; j < pLen ; j++) { //整数部分相加 int tmp = integer[j] + a.integer[j] + carry; ret.integer[ret.integerSize++] = tmp % 10; //保存结果 carry = tmp / 10; //更新进位 } if (carry != 0) { //当前进位不为0,进位并保存下来 ret.integer[ret.integerSize++] = carry; } return ret; } BigFloat operator += (const BigFloat& a) { *this = *this + a; return *this; } BigFloat operator * (const string& num2) { string num1 = str(); *this = mul(num1, num2); return *this; } BigFloat operator * (double value) { ostringstream num2; num2 << fixed << setprecision(n) << value;//保留精度 string num1 = str(); *this = mul(num1, num2.str()); return *this; } BigFloat operator * (BigFloat num2) { string num1 = str(); *this = mul(num1, num2.str()); return *this; } string str() { string res = ""; int i = integerSize - 1; while (integer[i] == 0 && i >= 0 )i--; //移除高位的0 if (i == -1) { res += "0"; } else { while (i >= 0) { //倒序输出整数部分 res += integer[i--] + '0'; } } int j = decimalSize - 1; while (decimal[j] == 0 && j >= 0) j--; //移除小数部分低位0,并保存小数部分有效长度 if (j != -1) { res += "."; for (int k = 0; k <= j; k ++) { //输出小数部分 res += decimal[k] + '0'; } } return res; } friend ostream& operator << (ostream& out, const BigFloat& x) { int i = x.integerSize - 1; while (x.integer[i] == 0 && i >= 0 )i--; //移除高位的0 if (i == -1) { out << "0"; } else { while (i >= 0) { //倒序输出整数部分 out << x.integer[i--]; } } int j = x.decimalSize - 1; while (x.decimal[j] == 0 && j >= 0) j--; //移除小数部分低位0,并保存小数部分有效长度 if (j != -1) { out << "."; for (int k = 0; k <= j; k ++) { out << x.decimal[k]; } } return out; } friend istream& operator >> (istream& in, BigFloat& x) { string s; in >> s; x = s; return in; } // 将字符串形式的数字(带小数点)转换为倒序存储的整数数组,并记录小数点位置 pair<vector<int>, int> stringToVector(const string& num) { vector<int> result; int decimalPos = 0; bool isDecimal = false; for (int i = num.size() - 1; i >= 0; --i) { if (num[i] == '.') { isDecimal = true; decimalPos = num.size() - 1 - i; } else { result.push_back(num[i] - '0'); } } if (!isDecimal) decimalPos = 0; return {result, decimalPos}; } // 将倒序存储的整数数组转换为字符串形式的数字,并处理小数点位置 string vectorToString(const vector<int>& num, int decimalPos) { string result; bool leadingZero = true; for (int i = num.size() - 1; i >= 0; --i) { if (leadingZero && num[i] == 0 && i >= decimalPos) continue; leadingZero = false; if (i == decimalPos - 1 && i != 0) { result.push_back('.'); } result.push_back(num[i] + '0'); } if (leadingZero) return "0"; if (decimalPos == 0) return result; if (result.size() <= decimalPos) result.insert(result.begin(), decimalPos - result.size(), '0'); return result; } // 高精度浮点数乘法 string mul(const string& num1, const string& num2) { auto [n1, d1] = stringToVector(num1); auto [n2, d2] = stringToVector(num2); vector<int> result(n1.size() + n2.size(), 0); for (size_t i = 0; i < n1.size(); ++i) { for (size_t j = 0; j < n2.size(); ++j) { result[i + j] += n1[i] * n2[j]; if (result[i + j] >= 10) { result[i + j + 1] += result[i + j] / 10; result[i + j] %= 10; } } } // 计算小数点位置 int decimalPos = d1 + d2; // 去掉前导0 while (result.size() > 1 && result.back() == 0) { result.pop_back(); } return vectorToString(result, decimalPos); } };
本文作者:Ke_scholar
本文链接:https://www.cnblogs.com/Kescholar/p/18357721
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步