c++ - 这个 min() 函数是如何工作的?

标签 c++ c bit-manipulation

我遇到了这段代码:

int __min(int a, int b) {
    return ((a)-(((a)-(b))&((b)-(a))>>31));
}

我可以想象它与 2s 补码有关,并且它仅适用于带符号的 32 位整数,但在那之后我迷路了。

我找到了 this question ,但我不认为这些功能是相关的,还是我错了?

所以我有两个问题:

  1. 为什么这个功能有效?
  2. 有没有一种情况(a<b)?a:b行不通而这个功能行得通,或者这个功能只是为了好玩而过于复杂?

编辑:该函数是为 GPU 编写的,所以我认为@Banex 可能是正确的,这样编写它的目的是为了避免分支。

最佳答案

这是为 32 位有符号值设计的。让我们一次分解一个步骤。

((b)-(a))>>31)

右移运算符本质上是取 32 位值中的最高位,并将其符号扩展到剩余的 31 位。这就是右移运算符处理有符号值的方式。

如果b大于a,减法结果为正,最高位为0,结果为0。

如果b小于a,减法结果为负,最高位为1,结果为-1。最高位向下移动到所有剩余位。 32位值中的所有位都会被置位,也就是-1。

您可以自己编写一个短程序来验证这一点,该程序将正值或负值放入 32 位 int,并将其右移 31 位;然后观察结果将是 0 或 -1。如您所知,在二进制补码算法中,值 -1 的所有位都已设置。

((a)-(b)) & (0 or -1, as the result of the previous operation).

因此,如果 b 小于 a,则右侧值的所有位都已设置,并且按位 & 的结果运算符是左侧值。或 a-b

如果 b 大于 a,则右侧值的所有位均为 0,并且 & 的结果为 0。

总结:

如果 b 小于 a,则上述表达式的计算结果为:

a-(a-b)

or

a-a+b

or

b

如果b大于a,则表达式的结果为

a - 0

or

a

关于c++ - 这个 min() 函数是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40318780/

相关文章:

c# - 您如何使用技术(已描述)处理 .Net 中的 C 结构和指针?

c++ - 交叉兼容系统时间库

c++ - 用于片段着色器的 OpenGL GLSL 绑定(bind)采样器

C语言中使用指针连接字符串

c - 如何在 C 中干净地终止线程?

c - 〜对整数值有什么作用?此操作的用法

java - 在 Java 中获取 int 的特定位子集

c++ - 使用 POD 结构的 reinterpret_cast 理解代码示例

x86 - 设置 AVX 寄存器(__m256i)中的各个位,需要 "random access"运算符

c++ - 使用 extern 'C' 后有没有办法重新启用名称修改?