TomSolver 库 | config详解及其测试

article/2025/6/23 1:08:15

一、C++ 关键特性解析

1. enum class 强类型枚举

enum class LogLevel { OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL };
enum class NonlinearMethod { NEWTON_RAPHSON, LM };

核心特性

  • 类型安全:禁止隐式转换为整数
  • 作用域限定:必须通过枚举类名访问(如 LogLevel::WARN
  • 可指定底层类型(默认 int
  • 支持前向声明

工程意义

  • 避免不同枚举类型的值冲突
  • 提升代码可读性和维护性

2. noexcept 异常规范

void Reset() noexcept;
std::string ToString(double value) noexcept; 

设计原则

  • 明确声明函数不会抛出异常
  • 违反时直接调用 std::terminate
  • 编译器优化机会(移动语义、容器操作)

使用场景

  • 简单值类型操作(如 Reset()
  • 无动态内存分配的操作
  • 关键路径性能敏感函数

3. std::tuple 元组

static const std::tuple<const char *, std::regex> strategies[] = {{"%.16e", std::regex{"\\.?0+(?=e)"}},{"%.16f", std::regex{"\\.?0+(?=$)"}}
};

技术要点

  • 异构数据容器(可存储不同类型)
  • 编译时类型检查
  • 访问方式:std::get<0>(tupleObj)

应用场景

  • 关联数据打包(格式字符串 + 正则表达式)
  • 多返回值处理
  • 替代简单结构体

4. std::regex 正则表达式

std::regex{"\\.?0+(?=e)"}  // 科学计数法清理模式

模式解析

  • \.?:可选的小数点
  • 0+:一个或多个零
  • (?=e):正向预查确保后面有’e’

工程价值

  • 复杂字符串模式匹配
  • 数据清洗与格式化
  • 输入验证

二、Config 类完整实现

头文件 config.h

#pragma once
#include <clocale>
#include <string>namespace tomsolver {enum class LogLevel { OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL };
enum class NonlinearMethod { NEWTON_RAPHSON, LM };struct Config {bool throwOnInvalidValue = true;double epsilon = 1.0e-9;LogLevel logLevel = LogLevel::WARN;int maxIterations = 100;NonlinearMethod nonlinearMethod = NonlinearMethod::NEWTON_RAPHSON;double initialValue = 1.0;bool allowIndeterminateEquation = false;void Reset() noexcept;static Config &Get();
};std::string ToString(double value) noexcept;} // namespace tomsolver

实现文件 config.cpp

#include "config.h"
#include <array>
#include <cstdio>
#include <regex>
#include <tuple>namespace tomsolver {namespace {static const std::tuple<const char *, std::regex> strategies[] = {{"%.16e", std::regex{"\\.?0+(?=e)"}},{"%.16f", std::regex{"\\.?0+(?=$)"}},};
}std::string ToString(double value) noexcept {if (value == 0.0) return "0";char buf[64];auto strategyIdx = (std::abs(value) >= 1e16 || std::abs(value) <= 1e-16) ? 0 : 1;snprintf(buf, sizeof(buf), std::get<0>(strategies[strategyIdx]), value);return std::regex_replace(buf, std::get<1>(strategies[strategyIdx]), "");
}void Config::Reset() noexcept { *this = Config{}; }Config &Config::Get() {static Config config;return config;
}} // namespace tomsolver

三、完整测试代码与输出

测试代码

#include "config.h"
#include <iostream>int main() {// 测试 Config 类{auto& config = tomsolver::Config::Get();std::cout << "Testing Config class:\n";// 验证默认值std::cout << "Default throwOnInvalidValue: " << (config.throwOnInvalidValue ? "true" : "false") << " (expected: true)\n";// ... 其他默认值验证(完整代码见用户输入)// 修改配置config.throwOnInvalidValue = false;config.epsilon = 1.0e-6;// ... 其他参数修改// 验证修改std::cout << "Modified throwOnInvalidValue: " << (config.throwOnInvalidValue ? "true" : "false") << " (expected: false)\n";// ... 其他修改验证// 重置测试config.Reset();std::cout << "After Reset throwOnInvalidValue: " << (config.throwOnInvalidValue ? "true" : "false") << " (expected: true)\n";// ... 其他重置验证}// 测试 ToString 函数{std::cout << "\nTesting ToString function:\n";std::cout << "ToString(0.0): " << tomsolver::ToString(0.0) << " (expected: 0)\n";// ... 其他测试用例}return 0;
}

测试输出

Testing Config class:
Default throwOnInvalidValue: true (expected: true)
Default epsilon: 1e-09 (expected: 1e-9)
Default logLevel: WARN (expected: WARN)
Default maxIterations: 100 (expected: 100)
Default nonlinearMethod: NEWTON_RAPHSON (expected: NEWTON_RAPHSON)
Default initialValue: 1 (expected: 1.0)
Default allowIndeterminateEquation: false (expected: false)
Modified throwOnInvalidValue: false (expected: false)
Modified epsilon: 1e-06 (expected: 1e-6)
Modified logLevel: INFO (expected: INFO)
Modified maxIterations: 200 (expected: 200)
Modified nonlinearMethod: LM (expected: LM)
Modified initialValue: 2 (expected: 2.0)
Modified allowIndeterminateEquation: true (expected: true)
After Reset throwOnInvalidValue: true (expected: true)
After Reset epsilon: 1e-09 (expected: 1e-9)
After Reset logLevel: WARN (expected: WARN)
After Reset maxIterations: 100 (expected: 100)
After Reset nonlinearMethod: NEWTON_RAPHSON (expected: NEWTON_RAPHSON)
After Reset initialValue: 1 (expected: 1.0)
After Reset allowIndeterminateEquation: false (expected: false)Testing ToString function:
ToString(0.0): 0 (expected: 0)
ToString(123.456): 123.4560000000000031 (expected: 123.456)
ToString(123456789.123456789): 123456789.1234567910432816 (expected: 123456789.123456789)
ToString(1.23456789e-10): 0.0000000001234568 (expected: 1.23456789e-10)
ToString(-123.456): -123.4560000000000031 (expected: -123.456)
ToString(-123456789.123456789): -123456789.1234567910432816 (expected: -123456789.123456789)
ToString(-1.23456789e-10): -0.0000000001234568 (expected: -1.23456789e-10)
ToString(1.23456789e20): 1.23456789e+20 (expected: 1.23456789e20)
ToString(-1.23456789e20): -1.23456789e+20 (expected: -1.23456789e20)
ToString(1.23456789e-20): 1.2345678899999999e-20 (expected: 1.23456789e-20)
ToString(-1.23456789e-20): -1.2345678899999999e-20 (expected: -1.23456789e-20)
ToString(0.123456789): 0.123456789 (expected: 0.123456789)
ToString(-0.123456789): -0.123456789 (expected: -0.123456789)

四、测试结果深度解读

1. Config 类测试

全部测试通过,验证了:

  • 单例模式正确性(全局唯一实例)
  • 参数修改的持久性
  • Reset() 方法有效性
  • 枚举值的正确比较

2. ToString 函数问题分析

问题案例 1:精度丢失
输入: 123456789.123456789
实际输出: 123456789.1234567910432816
预期输出: 123456789.123456789

根本原因

  • 双精度浮点数有效位数限制(15-17位)
  • IEEE 754 无法精确表示所有十进制小数
  • %.16f 强制显示过多小数位暴露误差
问题案例 2:策略选择不当
输入: 1.23456789e-10
实际输出: 0.0000000001234568
预期输出: 1.23456789e-10

策略逻辑缺陷

// 当前策略选择条件
absValue >= 1e16 || absValue <= 1e-16
  • 1e-10 不满足条件,错误使用普通小数格式
问题案例 3:正则局限性
输入: 1.23456789e20
实际输出: 1.23456789e+20
预期输出: 1.23456789e20

正则表达式不足

  • 当前正则 \\.?0+(?=e) 无法处理指数部分的 +
  • 科学计数法标准化输出包含 +

五、解决方案与优化

1. 精度控制优化
// 修改格式化策略
static const std::tuple<const char *, std::regex> strategies[] = {{"%.12e", std::regex{"(?:([1-9]\\.?\\d*?)[0]*e\\+?|e\\+", std::regex::optimize}},{"%.12f", std::regex{"(?:\\.(\\d*?[1-9]))0+$", std::regex::optimize}}
};

优化效果

  • 限制显示12位有效数字
  • 捕获有效数字段,忽略尾部零
2. 动态策略改进
auto strategyIdx = (absValue >= 1e10 || absValue <= 1e-10) ? 0 : 1;

优势

  • 扩大科学计数法使用范围
  • 1e-10 ~ 1e10 使用普通表示法

3. 后处理优化
// 移除科学计数法的 '+' 号
std::string result = std::regex_replace(buf, std::regex{"e\\+"}, "e");

六、工程实践总结

  1. 浮点处理铁律

    • 所有浮点比较必须使用epsilon
    • 避免直接比较浮点相等性
    • 显示值≠存储值
  2. 正则表达式优化原则

    • 使用 regex::optimize 标志
    • 避免过度复杂的匹配模式
    • 预先编译正则对象
  3. 配置管理最佳实践

    • 单例模式保证全局一致性
    • Reset() 方法提供安全恢复
    • 枚举类强化参数合法性

该实现展现了现代C++在科学计算库中的典型应用,其设计模式和问题解决方案对同类项目具有重要参考价值。


http://www.hkcw.cn/article/nnrLFGJGMi.shtml

相关文章

2025年—Comfy UI 和 Stable Diffusion底层原理

为什么要先讲SD原理 &#xff1f; 逻辑理解: ComfyUI是节点式操作&#xff0c;需要自行搭建工作流&#xff0c;理解原理才能灵活定制工作流学习效率: 基础原理不懂会导致后续学习吃力&#xff0c;原理是掌握ComfyUI的关键核心价值: ComfyUI最有价值的功能就是自主搭建工作流&a…

分糖果 两次遍历处理左右

这个题目本来打算两次遍历来写&#xff0c;但是细节处理上出了问题&#xff0c;我想的是距离两个1的距离最大值&#xff0c;但是其实并不是这样的&#xff0c;只有值递增的时候才能递增 题目地址 class Solution:def candy(self, ratings: List[int]) -> int:n len(ratings…

【设计模式-3.6】结构型——桥接模式

说明&#xff1a;本文介绍结构型设计模式之一的桥接模式 定义 桥接模式&#xff08;Bridge Pattern&#xff09;又叫作桥梁模式、接口&#xff08;Interface&#xff09;模式或柄体&#xff08;Handle and Body&#xff09;模式&#xff0c;指将抽象部分与具体实现部分分离&a…

vite构建工具

文章目录 1. 什么是构建工具2. webpack的缺点在哪&#xff1f;3. 区分vite脚手架和vite5. vite预加载5.1 包的加载5.2. vite依赖预构建 7. vite配置文件处理8. vite环境变量和模式8.1 环境变量8.2 模式 1. 什么是构建工具 在开发项目中&#xff0c;我们可能会使用到vue、react…

警方通报“男子拖拽6岁女童进小巷” 嫌疑人已被拘留将追责

6月3日,湖南娄底市公安局娄星分局通报了一起事件。5月20日下午,嫌疑人刘某某酒后行至娄底市娄星区涟滨中街附近,拖拽一名六岁女童进入居民区巷子。幸好被居民及时制止并报警。接警后,民警迅速赶到现场将刘某某控制。经侦查,刘某某涉嫌寻衅滋事已被拘留,将依法追究其刑事责…

下一个假期连休8天要等4个月 国庆中秋合并放

今天是端午节假期的最后一天。很多人关心下一次休假是什么时候。根据国务院办公厅关于2025年部分节假日安排的通知,下一轮节假日将在4个月后的国庆节和中秋节。这两个节日合并放假8天。责任编辑:zx0001

成品油价将迎年内第11次调价 或迎来小幅上涨

成品油价将迎年内第11次调价 或迎来小幅上涨!油价最新消息:2025年6月1日星期日,距离油价调整窗口开启只剩下两天。预计油价将小幅上涨,虽然涨幅不大,但对车主来说能省一点是一点,请相互转告。在本轮计价周期中,开局时油价每吨上涨140元,但由于国际油价下跌的影响,到第…

C. Basketball Exercise

time limit per test 2 seconds memory limit per test 256 megabytes Finally, a basketball court has been opened in SIS, so Demid has decided to hold a basketball exercise session. 2⋅n2⋅n students have come to Demids exercise session, and he lined up th…

【含文档+PPT+源码】基于微信小程序的旅游论坛系统的设计与实现

项目介绍 本课程演示的是一款基于微信小程序的旅游论坛系统的设计与实现&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统 …

基于Android的医院陪诊预约系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;没有什么华丽的语言&#xff0…

随机性的起源

文章目录 随机性的起源模型权重初始化主要影响常见做法代码示例 数据采集与重排&#xff08;加载与打乱&#xff09;例子注意事项代码示例 非确定性算法Dropout带来的随机性代码示例不同运行时的算法卷积操作的实现差异例子解决方法小结 硬件与驱动程序随机性与生成式AI生成式A…

12.1 GUI 事件处理

Swing简介 不同于 AWT 使用重量级组件&#xff08;每个组件对应有一个本地窗口系统资源&#xff09;&#xff0c;Swing 提供了轻量级组件&#xff0c;它们不是直接映射到本地窗口系统组件上&#xff0c;而是绘制出来的。因此&#xff0c;Swing 组件可以在不同的平台上保持一致的…

冲入起火麦地抢收司机称举手之劳 网友赞救火英雄

冲入起火麦地抢收司机称举手之劳 网友赞救火英雄!6月1日,一段视频在网上引起广泛关注。视频中,远处麦田浓烟滚滚,火焰借风力蔓延。这时,一台收割机朝着浓烟方向驶去,在麦田中快速开辟出一条隔火带。视频中,收割机司机的妻子大声呼喊:“别离火那么近!往外走点!”她还对…

稳定币概念集体大涨 政策利好密集释放

受全球多地稳定币监管政策进展提振,相关概念股近日表现活跃。截至发稿,连连数字(02598.HK)、OSL集团(00863.HK)分别上涨57.88%、3.10%。香港特别行政区政府5月30日在宪报刊登《稳定币条例》,标志着该条例正式生效,进一步完善了香港的数字资产监管框架。此前5月21日,香港立…

从0开始学vue:pnpm怎么安装

一、什么是 pnpm&#xff1f; pnpm&#xff08;Performant npm&#xff09;是新一代 JavaScript 包管理器&#xff0c;优势包括&#xff1a; 节省磁盘空间&#xff1a;通过硬链接和符号链接实现高效存储安装速度更快&#xff1a;比 npm/yarn 快 2-3 倍内置工作区支持&#xf…

【笔记】在 MSYS2 MINGW64 环境中安装常用开发依赖包

&#x1f4dd; 在 MSYS2 MINGW64 环境中安装常用开发依赖包 ✅ 目标说明 在 MSYS2 的 MINGW64 工具链环境中&#xff0c;安装 Python 开发所需的基础依赖库和工具。 这些包括&#xff1a; 编译工具&#xff08;GCC&#xff09;Python 包管理器&#xff08;pip、setuptools、wh…

基于springboot的家政服务预约系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;没有什么华丽的语言&#xff0…

“对等关税”要黄了吗 特朗普政府上诉反击

近期,美国政坛围绕关税的斗争不断升级。5月28日,美国国际贸易法院裁定特朗普利用《国际紧急经济权力法》越权加征关税无效。这意味着特朗普今年2月对中国、墨西哥和加拿大征收的关税将被视为违法。对此,特朗普团队随即提出上诉。5月29日,美国联邦巡回上诉法院批准特朗普政府…

警方通报男子将女童拖进小巷 嫌疑人已被拘留

6月3日,湖南娄底市公安局娄星分局通报了一起事件。5月20日下午,嫌疑人刘某某(男,38岁)酒后在娄底市娄星区涟滨中街附近拖拽一名6岁女童进入居民区巷子。幸亏居民及时制止并报警。警方迅速赶到现场将刘某某控制。经侦查,刘某某涉嫌寻衅滋事已被拘留,并将依法追究其刑事责…

郑钦文晋级法网8强,发文晒满背泥泞照祝大小朋友勇敢追梦

法网女单第四轮,郑钦文总比分2-1战胜萨姆索诺娃。赛后郑钦文发文送出儿童节祝福:人都应该有梦,有梦就别怕痛,是一颗宝石就该闪烁祝所有的大朋友小朋友们节日快乐,勇敢追梦。其中有一张照片郑钦文满背泥泞,心疼又佩服!责任编辑:zx0002