[英]Implementing logical negation with only bitwise operators (except !)
~ & ^ | + << >>
~ & ^ | + << >>
are the only operations I can use ~ & ^ | + << >>
是我可以使用的唯一操作
Before I continue, this is a homework question, I've been stuck on this for a really long time. 在我继续之前,这是一个功课问题,我已经坚持了很长时间。
My original approach: I thought that !x could be done with two's complement and doing something with it's additive inverse. 我原来的方法:我认为!x可以用两个补码完成,并用它的加法逆做一些事情。 I know that an xor is probably in here but I'm really at a loss how to approach this. 我知道xor可能在这里,但我真的不知道如何处理这个问题。
For the record: I also cannot use conditionals, loops, ==
, etc, only the functions (bitwise) I mentioned above. 为了记录:我也不能使用条件,循环, ==
等,只能使用上面提到的函数(按位)。
For example: 例如:
!0 = 1
!1 = 0
!anything besides 0 = 0
Assuming a 32 bit unsigned int: 假设一个32位无符号int:
(((x>>1) | (x&1)) + ~0U) >> 31
should do the trick 应该做的伎俩
Assuming x
is signed, need to return 0 for any number not zero, and 1 for zero. 假设x
已签名,则需要为任何不为零的数字返回0,为零返回1。
A right shift on a signed integer usually is an arithmetical shift in most implementations (eg the sign bit is copied over). 在大多数实现中,有符号整数的右移通常是算术移位(例如,符号位被复制)。 Therefore right shift x
by 31 and its negation by 31. One of those two will be a negative number and so right shifted by 31 will be 0xFFFFFFFF (of course if x = 0 then the right shift will produce 0x0 which is what you want). 因此,右移x
乘以31,其否定为31.其中一个将是负数,因此右移31将为0xFFFFFFFF(当然如果x = 0则右移将产生0x0,这是你想要的) 。 You don't know if x or its negation is the negative number so just 'or' them together and you will get what you want. 你不知道x或它的否定是负数,所以只是'或'它们在一起你会得到你想要的。 Next add 1 and your good. 接下来加1和你的好。
implementation: 执行:
int bang(int x) {
return ((x >> 31) | ((~x + 1) >> 31)) + 1;
}
The following code copies any 1 bit to all positions. 以下代码将任何1位复制到所有位置。 This maps all non-zeroes to 0xFFFFFFFF == -1
, while leaving 0
at 0
. 这会将所有非零映射到0xFFFFFFFF == -1
,而将0
保留为0
。 Then it adds 1, mapping -1
to 0
and 0
to 1
. 然后它添加1,映射-1
到0
和0
到1
。
x = x | x << 1 | x >> 1
x = x | x << 2 | x >> 2
x = x | x << 4 | x >> 4
x = x | x << 8 | x >> 8
x = x | x << 16 | x >> 16
x = x + 1
For 32 bit signed integer x 对于32位有符号整数x
// Set the bottom bit if any bit set.
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x ^= 1; // Toggle the bottom bit - now 0 if any bit set.
x &= 1; // Clear the unwanted bits to leave 0 or 1.
Assuming eg an 8-bit unsigned type: 假设例如8位无符号类型:
~(((x >> 0) & 1)
| ((x >> 1) & 1)
| ((x >> 2) & 1)
...
| ((x >> 7) & 1)) & 1
你可以做~x&1,因为它为0产生1,其他所有产生0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.