2012-04-23 73 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),那是允許的,不是嗎?