这个min()函数如何工作?

Pas*_*mer 5 c c++ bit-manipulation

我遇到了这段代码:

int __min(int a, int b) {
    return ((a)-(((a)-(b))&((b)-(a))>>31));
}
Run Code Online (Sandbox Code Playgroud)

我可以想象它与2s补码有关,它只适用于有符号的32位整数,但之后我就输了.

我发现了这个问题,但我不认为这些功能是相关的,还是我错了?

所以我有两个问题:

  1. 为什么这个功能有效?
  2. 是否存在(a<b)?a:b无法正常工作的情况,这个功能是否会过于复杂?

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

Sam*_*hik 2

它设计用于 32 位有符号值。让我们一步步分解。

((b)-(a))>>31)
Run Code Online (Sandbox Code Playgroud)

右移运算符本质上取 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).
Run Code Online (Sandbox Code Playgroud)

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

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

综上所述:

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

a-(a-b)

or

a-a+b

or

b
Run Code Online (Sandbox Code Playgroud)

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

a - 0

or

a
Run Code Online (Sandbox Code Playgroud)