2010-04-24 58 views
3

我很慚愧地承認,我不太瞭解位和位操作,因爲我可能應該這樣做。我試着通過寫一些'反轉位的順序'和'計數ON位'的功能來修復這個週末。我舉了一個here的例子,但是當我實現它時,我發現我必須循環,而< 29.如果我循環,而< 32(如在示例中)然後,當我嘗試打印整數(使用printBits函數我寫了)我似乎錯過了前3位。這對我來說沒有意義,有人可以幫我嗎?這個倒序位順序函數是怎麼回事?

感謝大家的幫助,我添加了評論以顯示我所做的更改。

int reverse(int n) 
{ 
    int r = 0; 
    int i = 0; 
    for(i = 0; i < 29; i++) //Should be i < 32 
    { 
     r = (r << 1) + (n & 1); //| instead of + to make it obvious I'm handling bits 
     n >>=1; 
    } 

    return r; 
} 

這裏是我的printBits功能:

void printBits(int n) 
{ 
    int mask = 0X10000000; //unsigned int mask = 0X80000000; 
    while (mask) 
    { 
     if (mask & n) 
     { 
      printf("1"); 
     } 
     else 
     { 
      printf("0"); 
     } 
     mask >>= 1; 
    } 
    printf("\n"); 
} 

和工作?反向功能

int reverse2(int n) 
{ 
    int r = n; 
    int s = sizeof(n) * 7; // int s = (sizeof(n) * 8) -1 

    for (n >>= 1; n; n >>=1) 
    { 
     r <<=1; 
     r |= n & 1; 
     s--; 


    r <<= s; 
    return r; 
} 
+1

記住你的循環是從零開始的。所以32是從0到31 ... – 2010-04-24 19:52:48

+0

您是否可以發佈您的PrintBits函數,以防萬一出現問題?它可能有幫助。 :-) – Jaxidian 2010-04-24 19:54:43

+0

此外,爲了跟進託尼的評論,這是一個整數,一個有符號的整數,所以你丟失了一點,因爲存儲符號(+/-)。所以現在循環是從0到30。也許你失去了一次必要的迭代,因爲對於n位,你需要循環n-1次。考慮一下 - 你必須做多少班次才能扭轉2位? 3位?等等...... – Jaxidian 2010-04-24 19:56:21

回答

3

您有:

int mask = 0x10000000; 

這裏有兩個問題。你沒有設置高位,如果你這樣做了,它仍然(可能)不起作用,因爲你的編譯器會在簽名的int上使用算術移位。

你想你的面具更改爲:

unsigned int mask = 0x80000000; 

對於算術移位,移位0x80000000權永遠不會變成零,符號位將被神奇地擴展到其他位。有關算術移位的更多細節,請參見here

2

相反的+,你應該使用|(按位或)。你應該使用< 32

+1

'+'和'|'在這裏會給出相同的結果。 – interjay 2010-04-24 19:55:29

+0

'+'或'|'在這裏沒有區別,'+'可能更清晰,爲什麼使用'|'? – 2010-04-24 19:55:52

+5

@Chris Dodd:'|'更清晰。你正在處理的是位,而不是算術。因此使用設計用於位操作的操作符。 – Ponkadoodle 2010-04-24 19:57:48

1

正如所寫,這會將n的低29位反轉爲r。 n的前三位將留在n中(向下移位29位)並不返回。

如果你看到別的東西,我會懷疑你的printBits函數有問題。

編輯

你printBits函數打印n的低29位,所以這一切纔有意義。

3

打印位錯誤,其0x80000000不是0x10000000。

>>> bin (0x80000000) 
'0b10000000000000000000000000000000' 
>>> bin (0x10000000) 
'0b10000000000000000000000000000' 

請參閱0x1 ...不設置最高位。

5
int mask = 0X10000000; 

將第28位置1。您想要0X80000000