2011-08-14 18 views
0

我需要將一個無符號整數向右移動超過32次,仍然得到零而不是隨機或原始數的正確答案。例如,8 >> 40應該= 0,但它返回一個隨機數。C - 需要一次將一個無符號整數移到一個地方。

我知道一次一個地方移動一個地方的循環可以解決這個問題,因爲它會填充零。不過,我目前的代碼不適用於某些原因。我究竟做錯了什麼?

unsigned int shiftR(unsigned int a, unsigned int b) { 
    unsigned int i=0; 
    while (i < b) { 
     a >> 1; 
     i++; 
    } 
    return a; 
} 

這給了我一個編譯警告,它沒有任何效果(a >> 1;)。怎麼來的?

謝謝!

回答

10

您想使用a >>= 1;a = a >> 1;這是因爲a >> 1將a右移一次並返回結果。它不分配結果a

+0

非常感謝! – RedFred

1

至於我記得C,你需要說A = A >> 1

+1

然而,如果這是你想要做的,a >> = b也可以代替你的所有代碼。 –

+0

a >> = b如果b是一些荒謬的東西,例如8 >> 500 = 8,那麼它仍然返回一個不正確的答案,在循環中它返回0. – RedFred

+0

這個循環很醜。至少用if(b> 32)a = 0來保護它,否則a >> = b。 –

0

正如其他人所指出的,你永遠不會重新分配a一個新值;該語句的結果並未用於任何事情,因此編譯器將其去掉。 a>>=1是你想要的。

我想補充一點,如果你想讓你的unsigned int爲32位,那就強制它。使用C99 stdint.h庫並使其成爲uint32_t - 很好,明確

0

一個循環,在一個時間

右移一個地方,你必須改變a >> 1;a >>= 1;

E.g 8 >> 40應該= 0,但它返回一個隨機數。

在C中,它是未定義的行爲向左或向右通過更多的地方比整數類型[0]的比特寬度移位的整數。步入未定義的行爲是非常壞不好,因爲什麼都不會發生,不好的事情可能會立即發生,在未來某個未知的事情會發生不好的事情,或者在不同的平臺或編譯器上發生不好的事情。

來處理這個正確的方法是手工檢查,如果你超過32米的地方轉移,然後手動給出0

[0]結果:http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html。您應該閱讀整個頁面,但具體的部分是「超大型轉移金額」。

0

a + 1增加1a,但不存儲任何地方的任何東西,因此a的值是未修改的。要使用增加的值更新值a,您必須執行a = a + 1a += 1。類似地將a中的整數值移動1,然後將移位的值存儲在a中,則需要執行a = a >> 1a >>= 1

因爲只有這樣做a >> 1不修改的a值時,編譯器適當地提醒你,這種說法沒有任何效果,這意味着保持本聲明或刪除也無所謂,因爲它沒有任何修改。

在你的情況下,你正在改變的值爲a,b nos時間,所以你可以簡單地使用a >>= b而不是迭代循環。

3

我需要將一個無符號整數向右移動超過32次,仍然得到零而不是隨機數或原始數的正確答案。

...那麼做那個?

unsigned int shiftR(unsigned int a, unsigned int b) { 
    return (b >= 32) ? 0 : a >> b; 
} 

爲什麼使事情複雜化?

相關問題