2017-08-09 57 views
2

對於較大的任務的一部分,我被要求實現一個函數,翻轉一個整數的任意位。問題是「整數」可能是c中的任何默認整數類型,從int8_t到uint64_t,我不知道它會是哪一個。 (事實上​​,我的代碼已經在所有這些類型的測試)與uint64_t移動不按預期工作

這是我的問題的嘗試:

//NOTE: g_int is the generic integer, it's typedef'd in a .h file 
g_int flip_bit(g_int b, uint8_t i){ 
    //Code that makes sure i is a valid amount to shift by, there's a macro 
    //that defines the upper bound of i in a .h file. 
    g_int flipped = b^(1<<i); 
    return flipped; 
} 

此代碼異或在b與1 i個位,而其它位在b與0.這應該翻轉i th位,而其餘的不變。對此,我測試了所有這些不同整數大小的代碼,然後將其轉入。但是,我的測試不夠充分,因爲我的代碼在int64_t和uint64_t上都失敗了。

我對int64_t和uint64_t做了什麼錯誤,還有什麼我可以做的,使我的方法工作而不完全改變它?

+0

當然,我可以進行編輯。 generic不是這個任務中類型的實際名稱,我只是快速改變它以表示它的含義。對困惑感到抱歉。 – UnknowableIneffable

+0

如何在.h文件中定義'g_int'?它在整個構建過程中始終是一樣的?它可能會影響'flip_bit()'的使用方式。 – chux

+0

對,對不起。我的意思是說,當我的代碼被測試時,有一堆不同的.h文件用相同的名稱對它進行測試,每次測試一個,併爲每個文件使用所有這些不同的整數類型。我的方法必須爲他們每個人工作。 – UnknowableIneffable

回答

5

此問題是由int的類型(其在合理的機器上具有32位)引起的。這意味着對於i大於或等於32的值執行移位(1<<i)將導致未定義的行爲。

這可以簡單地通過鑄造1執行變速之前鍵入g_int被固定:

g_int flip_bit(g_int b, uint8_t i){ 
    g_int flipped = b^(((g_int)1)<<i); 
    return flipped; 
} 
+3

唯一的修正是超出整數寬度的移位是*未定義的行爲*(不爲零)。 http://port70.net/~nsz/c/c11/n1570.html#6.5.7p4 –

+0

謝謝,我會更新它。 – UnknowableIneffable

+1

*未定義行爲*與「未定義值」不同。任何事情都可能發生,而不僅僅是意想不到的價值。 –