我的任务是制作一个函数,该函数返回int x是否适合C的缩写(如果满足,则返回1,否则返回0)。通常,这是一个相当简单的解决方案,但是我只能使用以下按位运算符: 〜&^ | + << >>。
还有更多规则:
我最多只能使用8个这些运算符。
不包含任何外部库。
不允许我使用任何条件语句(所以不能使用ifs,whiles, 等)。
我只能使用int类型的变量,而我不能 定义常量,例如0x0000ffff。但是,我可以使用0x0和0xff。
可以安全地假设int是32位,而short是16位。
我了解这些运算符的基本功能,但对实现逻辑感到困惑。有什么想法吗?
答案 0 :(得分:3)
假设两个补码(算术右移,舍弃溢出位的左移)和32位max_limit
,则:
int
当且仅当x<<16>>16 ^ x
符合16位x
时,为零。
由于要求我们为不适合返回0,为不适合返回1,因此我们可以返回:
short
证明:
如果! (x<<16>>16 ^ x)
适合x
,则short
•2 16 适合x
,因此int
产生没有溢出,并且x<<16
恢复x<<16>>16
(由于算术右移仅去除零是有效的除法运算,没有余数),之后x
为零。
如果x ^ x
短了,则x
溢出(我们假设会导致丢弃高位)。此外,它的值是x<<16
对某些短的y<<16
产生的值之一。然后y
必须产生与x<<16>>16
相同的值y<<16>>16
,该值不同于y
,因此x
不能为零。
答案 1 :(得分:0)
假设2个补码,您最初的想法是测试15位以外的所有前导位全为0或全为1。
11111111 11111111 1xxxxxxx xxxxxxxx /* for negative 16 bits int */
00000000 00000000 0xxxxxxx xxxxxxxx /* for positive 16 bits int */
假设算术右移,您可以右移15位以消除未知位,那么仅剩1或0(如果适合15位)
因此x>>15
应该为0或-1。
如果为0,则!(x >> 15)为true。
如果为-1,则!(〜(x >> 15))为true。
因此,您可以测试!(x>>15) | !(~(x>>15))
或者,您也可以这样写:!(x>>15) | !(~x>>15)
请注意,上面的表达式不假定x为32位,并且也可以用于测试int64是否适合int16 ...
还有很多其他方法...
由于您也可以使用+,因此(x>>15)+1
为0或1。
然后,您可以使用((x>>15)+1)>>1
清除最后一位。
如果以上表达式全为0(false),x
确实适合16位整数,因此您需要:
! (((x>>15)+1)>>1)
您可以根据自己的需要找到更多的表达方式...