Skip to content

Commit

Permalink
171 (#150)
Browse files Browse the repository at this point in the history
* fix #149

* fix #143
  • Loading branch information
wanghenshui authored Nov 3, 2024
1 parent b29d065 commit ad11b49
Show file tree
Hide file tree
Showing 2 changed files with 303 additions and 1 deletion.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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) |
| | | | | | | | | | |

### 特约供稿

Expand Down
300 changes: 300 additions & 0 deletions posts/171.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
---
layout: post
title: 第171期
---
# C++ 中文周刊 2024-11-03 第171期


[周刊项目地址](https://github.com/wanghenshui/cppweeklynews)

公众号

<img src="https://wanghenshui.github.io/cppweeklynews/assets/code.png" alt="" width="30%">

点击「查看原文」跳转到 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<std::string, OptionTypeInfo>
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 <numeric>
#include <cmath>
#include <iostream>


class FloatingPointComparator {
private:
static constexpr double DEFAULT_EPSILON = 1e-10;
static constexpr double MIN_NORMAL = std::numeric_limits<double>::min();
static constexpr double MAX_NORMAL = std::numeric_limits<double>::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<std::uint64_t>(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<std::uint64_t>(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<double>::min(),
std::numeric_limits<double>::denorm_min(),
std::numeric_limits<double>::quiet_NaN(),
std::numeric_limits<double>::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)

0 comments on commit ad11b49

Please sign in to comment.