我遇到了这段代码:
int __min(int a, int b) {
return ((a)-(((a)-(b))&((b)-(a))>>31));
}
我可以想象它与2s补码有关,它只适用于有符号的32位整数,但之后我就迷失了。
我找到this question,但我不认为这些功能是相关的,还是我错了?
所以我有两个问题:
(a<b)?a:b
无法正常工作的情况,这个功能会不会过于复杂?编辑:该函数是为GPU编写的,所以我认为@Banex可能是正确的,因为这样做是为了避免分支。
答案 0 :(得分:2)
这适用于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
答案 1 :(得分:0)
表达式
((a)-(b))&((b)-(a))>>31
即。没有最多余的括号
(a - b) & (b - a) >> 31
评估为
a - b
如果a&gt; b,以及
0
否则,如果最终从a中减去它,则与
相同if (a > b)
return (a - (a - b));
else
return (a - 0);