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位整数,但之后我就输了.
我发现了这个问题,但我不认为这些功能是相关的,还是我错了?
所以我有两个问题:
(a<b)?a:b无法正常工作的情况,这个功能是否会过于复杂?编辑:该函数是为GPU编写的,所以我认为@Banex可能是正确的写这个目的是为了避免分支.
它设计用于 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)
| 归档时间: |
|
| 查看次数: |
143 次 |
| 最近记录: |