diff --git a/README.md b/README.md index b22351f..86e9ae5 100644 --- a/README.md +++ b/README.md @@ -28,10 +28,12 @@ RSS使用仓库的release RSS [链接](https://github.com/wanghenshui/cppweeklyn ## 2024 -| [161](./posts/161.md) | [162](./posts/162.md) | [163](./posts/163.md) | [164](./posts/164.md) | [165](./posts/165.md) | [166](./posts/166.md) | [167](./posts/167.md) | [168](./posts/168.md) | [169](./posts/169.md) | [170](./posts/170.md) | +| [171](./posts/171.md) | | | | | | | | | | | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| [161](./posts/161.md) | [162](./posts/162.md) | [163](./posts/163.md) | [164](./posts/164.md) | [165](./posts/165.md) | [166](./posts/166.md) | [167](./posts/167.md) | [168](./posts/168.md) | [169](./posts/169.md) | [170](./posts/170.md) | | [151](./posts/151.md) | [152](./posts/152.md) | [153](./posts/153.md) | [154](./posts/154.md) | [155](./posts/155.md) | [156](./posts/156.md) | [157](./posts/157.md) | [158](./posts/158.md) | [159](./posts/159.md) | [160](./posts/160.md) | | | | | | [145](./posts/145.md) | [146](./posts/146.md) | [147](./posts/147.md) | [148](./posts/148.md) | [149](./posts/149.md) | [150](./posts/150.md) | +| | | | | | | | | | | ### 特约供稿 diff --git a/posts/171.md b/posts/171.md new file mode 100644 index 0000000..268b2d0 --- /dev/null +++ b/posts/171.md @@ -0,0 +1,300 @@ +--- +layout: post +title: 第171期 +--- +# C++ 中文周刊 2024-11-03 第171期 + + +[周刊项目地址](https://github.com/wanghenshui/cppweeklynews) + +公众号 + + + +点击「查看原文」跳转到 GitHub 上对应文件,链接就可以点击了 + +qq群 [点击进入](https://qm.qq.com/q/6NGizNPyG4) 满了加这俩 729240657 866408334 + +[RSS](https://github.com/wanghenshui/cppweeklynews/releases.atom) + +欢迎投稿,推荐或自荐文章/软件/资源等,评论区留言 + +本期文章由 HNY 赞助 在此表示感谢 + +本期内容较少,掺杂一些互动 + +--- + +## 资讯 + +标准委员会动态/ide/编译器信息放在这里 + +[编译器信息最新动态推荐关注hellogcc公众号 本周更新2024-10-30 第278期 ](https://mp.weixin.qq.com/s/NSuihKy3ku3h00FnwO2PxQ) + + +## 文章 + +### [How useful is the hint passed to the std::unordered_… collections? ](https://devblogs.microsoft.com/oldnewthing/20241028-00/?p=110428) + + +emplace_hit 在有序map有很大作用,但是在无序容器,由于不允许重复,hint基本没啥用 + +但无序容器存在允许重复值的 multixx,这种场景可以用,一般来说用不着 + +总结了一个表格 + + +| 实现 |unordered_multixx |unordered_xx| +|--| -------------------------------- | ---------------------- | +|是否允许重复| 是 | 否 | +| msvc/STL | 如果匹配就是用 | 如果匹配就使用 | +| clang/libcxx | 忽略 | 如果匹配就使用| +| gcc/libstdc++ (large or fast) | 忽略 | 如果匹配就使用| +| gcc/libstdc++ (small and slow) | 忽略 |使用 | + + +libstdc++针对不同key的hash有快慢识别,默认是快的 (long double慢) 这里有坑不知道大家记得不 + +群友mapleFU投稿 + +> 之前用 hint 优化过一些有序容器相关的处理( io range 维护什么的),感觉还是挺有用的 +> + +### 工厂函数的几种实现 + +其实就是static map,可以有多种维护方法 + +- 可以利用类来封装,利用宏生成多个static变量构造,来注册到map +- singleton模版注册也可以,利用模版实例化来调用注册到map 这两种都适合分散写法 + +这里有个例子 https://www.cnblogs.com/qicosmos/p/5090159.html + +我就不贴代码了,脑补一下就有了 + +- 直接注册也可以,比如 + +```cpp +static std::unordered_map + lru_cache_options_type_info = { + {"capacity", + {offsetof(struct LRUCacheOptions, capacity), OptionType::kSizeT, + OptionVerificationType::kNormal, OptionTypeFlags::kMutable}}, + {"num_shard_bits", + {offsetof(struct LRUCacheOptions, num_shard_bits), OptionType::kInt, + OptionVerificationType::kNormal, OptionTypeFlags::kMutable}}, + {"strict_capacity_limit", + {offsetof(struct LRUCacheOptions, strict_capacity_limit), + OptionType::kBoolean, OptionVerificationType::kNormal, + OptionTypeFlags::kMutable}}, + {"high_pri_pool_ratio", + {offsetof(struct LRUCacheOptions, high_pri_pool_ratio), + OptionType::kDouble, OptionVerificationType::kNormal, + OptionTypeFlags::kMutable}}, + {"low_pri_pool_ratio", + {offsetof(struct LRUCacheOptions, low_pri_pool_ratio), + OptionType::kDouble, OptionVerificationType::kNormal, + OptionTypeFlags::kMutable}}, +}; +``` + +直接注册也未尝不可,直观,适合聚集写法 + +依赖dlopen也可以,不过属于杀鸡牛刀 + + +## 如何判断一个数字是不是浮点数0?判断0正负 https://godbolt.org/z/jcqc38qqW + +直接贴代码 + +```cpp +#include +#include +#include + + +class FloatingPointComparator { +private: + static constexpr double DEFAULT_EPSILON = 1e-10; + static constexpr double MIN_NORMAL = std::numeric_limits::min(); + static constexpr double MAX_NORMAL = std::numeric_limits::max(); + +public: + // 基本的零值检查 + static bool isZero(double value) { + return std::abs(value) < DEFAULT_EPSILON; + } + + // 带自定义误差的零值检查 + static bool isZeroWithEpsilon(double value, double epsilon) { + return std::abs(value) < epsilon; + } + + // 相对误差检查 + static bool isZeroRelative(double value) { + if (std::abs(value) < MIN_NORMAL) { + return true; + } + return std::abs(value) < DEFAULT_EPSILON * std::max(1.0, std::abs(value)); + } + + // IEEE 754 特殊值检查 + static bool isSpecial(double value) { + return std::isnan(value) || std::isinf(value); + } + + // 判断是否为正负零 + static bool isExactZero(double value) { + return value == 0.0 || value == -0.0; + } + + // 综合判断 + static bool isEffectivelyZero(double value) { + if (isSpecial(value)) { + return false; + } + if (isExactZero(value)) { + return true; + } + return isZeroRelative(value); + } +}; + +class ZeroSignChecker { +public: + static bool isNegativeZero(double value) { + if (value != 0.0) return false; + /* + union { + double d; + uint64_t u; + } u = {value}; + return (u.u >> 63) == 1; + */ + auto u = std::bit_cast(value); + // 检查符号位(最高位) + return (u >> 63) == 1; + } + + static bool isPositiveZero(double value) { + if (value != 0.0) return false; + /* + union { + double d; + uint64_t u; + } u = {value}; + return (u.u >> 63) == 0; + */ + auto u = std::bit_cast(value); + + // 检查符号位 + return (u >> 63) == 0; + } + static bool isPositiveZeroV2(double value) { + return value == 0.0 && !std::signbit(value); + } + + static bool isNegativeZeroV2(double value) { + return value == 0.0 && std::signbit(value); + } + + static bool isNegativeZeroCoreDump(double value) { + if (value != 0.0) return false; + return std::isinf(1.0 / value) && (1.0 / value < 0); + } + + static bool isPositiveZeroCoreDump(double value) { + if (value != 0.0) return false; + return std::isinf(1.0 / value) && (1.0 / value > 0); + } +}; + +// 使用示例 +void testZeroSign() { + double pzero = 0.0; + double nzero = -0.0; + + std::cout << "Positive zero: " << ZeroSignChecker::isPositiveZero(pzero) << std::endl; + std::cout << "Negative zero: " << ZeroSignChecker::isNegativeZero(nzero) << std::endl; + std::cout << "Positive zero: " << ZeroSignChecker::isPositiveZeroV2(pzero) << std::endl; + std::cout << "Negative zero: " << ZeroSignChecker::isNegativeZeroV2(nzero) << std::endl; +} + +// 使用示例 +void testFloatingPoint() { + double values[] = { + 0.0, + -0.0, + 1e-15, + 1e-10, + std::numeric_limits::min(), + std::numeric_limits::denorm_min(), + std::numeric_limits::quiet_NaN(), + std::numeric_limits::infinity() + }; + + for (double val : values) { + std::cout << "Value: " << val << std::endl; + std::cout << "Is zero? " << FloatingPointComparator::isEffectivelyZero(val) << std::endl; + std::cout << "Is special? " << FloatingPointComparator::isSpecial(val) << std::endl; + std::cout << "Is exact zero? " << FloatingPointComparator::isExactZero(val) << std::endl; + std::cout << "-------------------" << std::endl; + } +} + +int main() { + testFloatingPoint(); + testZeroSign(); + return 0; +} +``` + +## 为什么 exit() 函数不是线程安全的? https://www.zhihu.com/question/2278762213/ + +主要原因 exit语义等同于从main 返回,会涉及到资源释放等相关流程,自然引入竞争问题 + +避免全局资源释放,使用quick_exit + +另外直接列一下各种exit区别 https://learn.microsoft.com/en-us/previous-versions/6wdz5232(v=vs.140) + +- exit 执行完整的 C 库终止过程,终止进程,并向主机环境提供提供的状态代码。 +- _Exit 执行最少的 C 库终止过程,终止进程,并向主机环境提供提供的状态代码。 +- _exit 执行最少的 C 库终止过程,终止进程,并向主机环境提供提供的状态代码。 +- quick_exit 执行快速 C 库终止过程,终止进程,并向主机环境提供提供的状态代码。 +- _cexit 执行完整的 C 库终止过程并返回给调用方。不终止进程。 +- _c_exit 执行最少的 C 库终止过程并返回给调用方。不终止进程。 + +## VC++中 log10(1e-23f) 向下舍入时,结果错误。如何解决? https://www.zhihu.com/question/1790209844/ + +msvc的log10f 和gcc libm的log10f行为不一样。大概实现算法有区别 + +两种结果都是符合标准的,毕竟round + +## 互动环节 + +熬夜看了英雄联盟S14总决赛,BLG vs T1, 2:3 本来2:1很有机会,但 + +第四局第五局的faker真的发挥了200%的水平,逆转夺冠 + +我看的很难受。尤其是赛后很多人踩脸 + +我不知道为什么全华班追求冠军是一种过错 + +什么开香槟不谦逊都成了罪过,怎么给自己打气也要批评? + +星际韩国包圆,李培楠也努力追求冠军不放弃 + +街霸日本包圆,曾卓君也努力追求冠军 + +dota有wings,就算lgd ti10打的气人也是追求过了 + +唯独lol,我是真无法理解有这么多喜欢狗仗人势的观众 + +这样的环境,真令人遗憾 + +也许这次就相当于dota ti10吧 大家记住了水人泼高地记住了on出乱送,然后顺便骂捞批捞底座赛区杂交赛区 + +真令人遗憾 + +--- + +[上一期](https://wanghenshui.github.io/cppweeklynews/posts/170.html) [下一期](https://wanghenshui.github.io/cppweeklynews/posts/172.html)