使用按位运算符,找到逻辑不等价

时间:2011-09-04 00:35:09

标签: c logic bit-manipulation

仅使用

<< >> | ^ & +

如何创建一个与逻辑非运算符(!)等效的函数?

现在我有:

int i = (~x + 1) >> 31; 
int j = (x + 1) >> 31; 
i = i | j; 
i = i & 1; 
return i ^ 1;

它适用于所有事情,但-1

3 个答案:

答案 0 :(得分:3)

我将假设您正在使用32位已签名的int,并使用2的补码表示法。关于数字0的独特之处在于,0和它的否定都没有1为符号位。如果允许您使用否定运算符( - ):

,此代码将起作用
int not(int x)
{
    return (-x | x) >> 31 & 1 ^ 1;
}

你不能使用减号,但这没关系,因为对于所有x,我们知道-x等于~x + 1等于(x ^ -1) + 1。这就是2的补码表示法的工作原理。所以最后的答案是:

int not(int x)
{
    return ( (x^-1)+1 | x ) >> 31 & 1 ^ 1;
}

编辑1: 好的,这里是函数的“ANSI”版本,它没有假设int的大小,也不依赖于右移有符号int的未定义行为。它适用于MinGW:

int not(int x)
{
    unsigned int y = x;
    return (( ((y^-1)+1) | y ) >> (sizeof(x)*8-1)) ^ 1;
}

答案 1 :(得分:0)

假设x是32位无符号值:

x = x | (x >> 1)
x = x | (x >> 2)
x = x | (x >> 4)
x = x | (x >> 8)
x = x | (x >> 16)

此时,如果x为0,则它​​仍为0.如果它具有非零值,则它现在具有位模式111 .... 111。

使用双补码表示,您现在可以简单地添加1并获得所需的结果:

x = x + 1

这个解决方案假定了整数表示,类型等等。

(上面的“代码”当然不是有效的C代码。)

答案 2 :(得分:0)

有点'作弊',但是:

bool logicalNot(int i)
{
    return((bool)i ^ true);
}

我假设关于函数组合/类型转换/隐式类型转换的规则中没有任何内容?