C 说明32位带符号整数是否为2的幂
我需要确定一个有符号的32位数字是否是2的幂。到目前为止,我知道要做的第一件事是检查它是否为负数,因为负数不能是2的幂。 然后我需要看看接下来的数字是否有效等等。。。所以我可以这样写:C 说明32位带符号整数是否为2的幂,c,binary,logic,bit-manipulation,C,Binary,Logic,Bit Manipulation,我需要确定一个有符号的32位数字是否是2的幂。到目前为止,我知道要做的第一件事是检查它是否为负数,因为负数不能是2的幂。 然后我需要看看接下来的数字是否有效等等。。。所以我可以这样写: // Return 1 if x is a power of 2, and return 0 otherwise. int func(int x) { return ((x != 0) && ((x & (~x + 1)) == x)); } 但对于我的任务,我只能使用其中20
// Return 1 if x is a power of 2, and return 0 otherwise.
int func(int x)
{
return ((x != 0) && ((x & (~x + 1)) == x));
}
但对于我的任务,我只能使用其中20个运算符:
! ~ & ^ | + << >>
!~&^ |+>
没有等式语句、循环、强制转换或语言构造
所以我试着转换相等部分,我知道!(a^b)与a==b是一样的,但我似乎不能完全理解它。有没有关于如何向允许的操作员隐瞒的想法?蒂姆的评论让我感到羞愧。让我试着帮你自己找到答案
就位操作而言,
x
是2的幂是什么意思?这意味着只有一位设置为1。我们怎么能做这样一个把戏,把那个位变成0,其他的可能变成1?那么&将给出0?用单一的表达?如果你发现了,你就赢了。想想这个。。。任何2减1的幂都是0加1的字符串。您可以通过x+~0
实现负1。想想1的字符串从什么地方开始,与2的幂次中的单个1相关。试试以下想法:
~!!x+1给出了一个掩码:如果
x==0,则为0;如果
x,则为-1=0
如果(x&(~x+1))^x
最多设置了1位,则为0,否则为非零,除非x
为~x
,在这种情况下,结果未定义。。。为了避免这种情况,您可以使用位移位将其拆分为多个部分,但我认为您将超过操作限制INT\u MIN
- 您还需要检查符号位,因为负值不是二的幂
顺便说一句,听起来你的指导老师不知道C中的有符号溢出是UB。他应该为无符号整数编写这些问题。即使您希望在语义上将值视为有符号的值,也需要使用无符号算术来执行这样有意义的位运算。在C中使用位运算符来解决一些问题是有趣而有效的。在这个问题上,我们需要处理两个检查:
int ispower2(int x)
{
int ispositive= ! ( (x>>31) ^ 0) & !!(x^0);
int temp= !((x & ~x+1) ^ x);
return temp & ispositive;
}
最后一次和操作。1到2次检查将生成iPower(2)功能的结果 首先,在您的解决方案中
return ((x > 0) && ((x & (~x + 1)) == x));
因为负数不能是2的幂。
根据您的要求,我们需要将“>”、“&&”、“==”转换为允许的运算符
首先考虑“>”,一个大于0的整数,其符号位为1,而不是0;所以我们考虑
~(x >> 31) & (x & ~0)
如果x为非正数,则上面的表达式将返回一个非零数。请注意~0=-1,即0x11111111。我们使用x&~0来检查这个整数在每个数字上是否都是0
其次,我们考虑“& &”。这非常简单——我们只需要得到0x01&0x01就可以返回1。因此,这里我们需要在第一个答案前面添加(!!),如果它返回一个非零数,则将其更改为0x01
最后,我们考虑“==”。为了测试A和B的公平性,我们只需要
!(A ^ B)
所以最后我们有
return (!!(~(x >> 31) & (x & ~0))) & (!((x&(~x+1)) ^ x))
这似乎是个家庭作业问题。请不要简单地复制和粘贴。我的答案有点尴尬,可能会有所改进。如果有人能找到一种方法来回答这个问题而不只是给出答案,那将是一件有趣的事情。在这种情况下,一个非常有用的技巧是
!!x
。这将使数字正常化,因此0变为0,而非-0变为1。它甚至是高效的(编译器对此进行了优化)。我总是遇到麻烦!!如果x=2,那么!x=1,然后!!x=0。如果x=0!x=0和!!x=1?我是否可以为“不称职的CS讲师x处理-!~&^+
问题”打开一个新的stackexchange站点提案?这已经到了我们有足够的时间来处理整个站点的地步……我认为如果讲师也理解C,这些问题会很好,但按照他/她所说的方式,这些问题在C中是无法解决的,并且期望的“解决方案”充满了未定义的行为(这可以通过切换到无符号算术来解决)。我还认为很不幸,班上的一个学生发现/知道堆栈溢出,并告诉全班同学来这里为他们完成作业……你觉得他们怎么样?老师通常都是没有行业经验的人,这总是让我感到痛苦。他们唯一的经验就是玩弄,我真的不明白。作为一个在学术界工作过的人(承认是数学而不是计算机科学),我总是希望学术工作中对精确定义的严谨和关注。然而,我们一次又一次地看到,在CS作业中,讲师显然不关心他们正在使用的语言的精确定义和规格……这个问题意味着1@Peter,有符号32位数字为否1@Peter:如果你问的是整数溢出,这并不罕见。欢迎来到SO,谢谢你