我遇到了这段代码:
int __min(int a, int b) {
return ((a)-(((a)-(b))&((b)-(a))>>31));
}
我可以想象它与 2s 补码有关,并且它仅适用于带符号的 32 位整数,但在那之后我迷路了。
我找到了 this question ,但我不认为这些功能是相关的,还是我错了?
所以我有两个问题:
- 为什么这个功能有效?
- 有没有一种情况
(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/