我正在尝试使用位操作在C中实现if语句。以下代码似乎有效:
// if (x) then y else z
int conditional(int x, int y, int z) {
int v = (!!x); //v is 1 or 0
return ((v<<31)>>31)&y | ((~v<<31)>>31)&z;
}
但是,当我在最后一行将“|”替换为“+”时,当x=0x8000000,y=0x8000000,z=0x7fffffff时,代码失败。它返回0而不是0x8000000。
所以我的问题是:为什么下面的失败?谢谢!
((v<<31)>>31)&y + ((~v<<31)>>31)&z
编辑:
我知道|是按位或+是加法。但在这种情况下,v是1或0,所以(v>31)要么是所有的1,要么是所有的0。y | 0x00000000应该与y+0x00000000相同,对吧?具体来说,v是1。所以上面输入的结果应该是y,但是使用“+”时返回0。
最佳答案
恐怕我们得用数学。
变量的最高位被设置,因此加倍等于左移1位,这等于溢出。所有剩余的位都是0。因此结果是0。
请记住,|
是按位||
的,不会将值传递到其他二进制数字。+
是的。
所以说,如果a
和b
是位向量空间的函数/向量(在你的例子中不是这样的话)orthogonal base
和a|b
是相等的,但只有那时。
更新:
这里的根本原因是运算符优先级:(降序)a+b
+
&
。
所以
((v<<31)>>31)&y + ((~v<<31)>>31)&z
变成
((v<<31)>>31) & (y + ((~v<<31)>>31)) & z