c++ - 为什么在 C++ 中使用 std::atomic<double>、std::atomic<float> 时,compare_exchange_strong 会失败?

标签 c++ c++11 concurrency atomic

我正在阅读《C++ 并发实践》第 5 章。 本章说,

Note that although you can use std::atomic<float> or std::atomic<double>, because the built-in floating point types do satisfy the criteria for use with memcpy and memcmp, the behavior may be surprising in the case of compare_exchange_strong. The operation may fail even though the old stored value was equal in value to the comparand, if the stored value had a different representation. Note that there are no atomic arithmetic operations on floating-point values. You’ll get similar behavior with compare_exchange_strong if you use std::atomic<> with a user-defined type that has an equality-comparison operator defined, and that operator differs from the comparison using memcmp—the operation may fail because the otherwise-equal values have a different representation.

但我不明白为什么会这样。

  1. 如果float和double可以使用memcpy和memcmp,那么做compare_exchange_strong这样的原子操作有什么问题呢?

  2. 我也无法使用compare_exchange_weak?

  3. 上一段中,“差异表示”是什么意思?

最佳答案

IEEE-754 float 使用有符号/数值格式来确定尾数的符号。也就是说,有一个符号位,然后有代表正数的位。如果设置了符号位,则该数字被解释为负数。

当然,如果所有数字(和指数)位均为 0,并且设置了符号位,则将产生“数字”-0.0。就现实世界的人类数学而言,不存在“负0”。所以从逻辑上讲,这样的数字应该被视为相当于+0.0。普通的浮点比较逻辑正是这样做的。但这两个等值(value)以不同的二进制表示形式存储;一个已设置符号位;另一个没有。

因此,如果您对两个浮点值的二进制表示进行比较(这是 atomic_compare_* 操作将执行的操作),那么 -0.0 将不会被视为等于 +0.0。

在其他情况下,IEEE-754 相等性测试可能会出错,但这是最容易解释的一种情况。

关于c++ - 为什么在 C++ 中使用 std::atomic<double>、std::atomic<float> 时,compare_exchange_strong 会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66566810/

相关文章:

c++ - 没有带有 unordered_map 的模板函数实例

c++ - 声明一次 C++ 后更改枚举

c++ - "error: use of deleted function"在 move 构造函数中对 unique_ptr 调用 std::move 时

c++ - QMap::operator[](const Key & key) 为什么按值返回?

concurrency - 为什么函数会提前返回?

multithreading - Flutter Dart : How can we achieve multithreading like python or java in dart

c++ - 如何在 Haar Cascade 分类过程中查看阳性

C++ 模板方法未知返回类型

c++ - 函数参数包后跟其他参数的模板参数推导

java - 从另一个线程读取共享变量(Effective Java #66)