2012-04-23 97 views
3

我有我的位操作课外练习的最后一个问题的麻烦。该函数应该返回1,如果任何奇数位被设置为1 这是我到目前为止有:位运算用C - AnyOddBit

int anyOddBit(int x) { 
    return (x & 0xaaaaaaaa) != 0; 
} 

完美的作品,但我不允许使用一个常量,大的(只允许0到255,0xFF)。我也不允许使用=

具体来说,这是我有限的使用:

Each "Expr" is an expression using ONLY the following: 
    1. Integer constants 0 through 255 (0xFF), inclusive. You are 
     not allowed to use big constants such as 0xffffffff. 
    2. Function arguments and local variables (no global variables). 
    3. Unary integer operations ! ~ 
    4. Binary integer operations &^| + << >> 

我无法弄清楚如何在这些限制之内做到这一点,我真的如果有人能指引我朝着正确的方向感谢。提前致谢!

+0

那么如何让比较小的值(S)? – 2012-04-23 01:05:18

回答

3

您可以使用:

!!(( (x  & 0xff) 
    | ((x >> 8) & 0xff) 
    | ((x >> 16) & 0xff) 
    | ((x >> 24) & 0xff) 
) & 0xaa) 

“内部”位,其中OR放在一起的每一个源八位字节,会给你在哪里,如果相当于位在任何源八位字节设置每个位设置一个字节。所以,如果其中一个奇数位在源八位组中被设置,它也将被设置在目标八位组中。

然后,通过与0xaa进行简单的“与”运算,如果不设置奇数位,则会得到零值,如果设置了任何奇数位,则会得到非零值。

然后,由于您需要0或1,并且不能使用!=,因此您可以通过!!(两个逻辑非运算符)获得类似的效果。它的工作原理是因为!(any-non-zero-value)0!01


为了与12个运营商做只(而不是13按我上面原来的解决方案),可以去除& 0xff>> 24值,因为它实际上不是必要的(零位从移入左边):

!!(( (x  & 0xff) 
    | ((x >> 8) & 0xff) 
    | ((x >> 16) & 0xff) 
    | ((x >> 24)  ) 
) & 0xaa) 

事实上,你甚至可以做得更好。最后& 0xaa无论如何都将清除所有的高24位,从而不需要& 0xff部分(也一行配合以及):

!!((x | (x >> 8) | (x >> 16) | (x >> 24)) & 0xaa) 

那得到它下降到9个运营商。

+0

好吧,这是有道理的吧!谢谢!我只需要弄清楚如何将运营商的数量减少1。显然我只允许12个运营商的功能,这个具有13 – 2012-04-23 01:38:38

+0

@Cory,没有公平改变游戏规则已经开始:-)后然而,你可以摆脱0xff'的'&对于'>> 24'值 - 它实际上并不需要。 – paxdiablo 2012-04-23 01:40:48

+0

啊,谢谢主席先生! – 2012-04-23 01:44:08

4

你可以做你的OR提前与运算的:

((x>>0) | (x>>8) | (x>>16) | (x>>24)) & 0xaa 

初始变速(x >> 0)将被优化掉了 - 它的存在是有一致的外观。

+0

我不能使用||运算符,只有逻辑或。 – 2012-04-23 01:20:18

+0

@Cory,那是_is_逻辑或。你可以使用的是_bitwise_或'|'。 – paxdiablo 2012-04-23 01:21:57

+0

我说错,我们对此深感抱歉。我被允许使用按位或不合逻辑或。 – 2012-04-23 01:22:40

1

0xaaaaaaaa基本上是(0xaa << 24) | (0xaa << 16) | (0xaa << 8) | (0xaa),那是允许的,不是吗?