2010-01-19 90 views
1

我想寫一個位旋轉函數,我試圖得到更多的說明sizeof運算符。因爲我不知道我需要什麼類型的數字對象的旋轉,我想我需要使用sizeof操作符的旋轉位,使用sizeof運算符

unsigned rotator(unsigned object, int count) 

這個函數的object是要旋轉的對象和數量是多少位移動。我想象,如果我有一個8位的號碼,我首先會確定要旋轉位的實際數量(因爲人可以數= 20例如,所以我會做這樣的事情:

int actualBitRotation; 
if (count > sizeof(object)) { 
    actualBitRotation = count % sizeof(object); 

但是我認爲我還是沒有正確理解sizeof,我嘗試閱讀關於它的在線資源,並從另一個問題上得到了該板上的一些幫助,但我認爲我沒有得到它,我知道sizeof返回數字在對象中的字節,所以我會包括,而是做一些的更喜歡

int actualBitRotation; 
if (count > (sizeof(object) * CHAR_BIT) { 
    actualBitRotation = count % (sizeof(object) * CHAR_BIT); 
} 

謝謝!

回答

3

sizeof()會返回字節數,所以您需要乘以CHAR_BIT以獲取位數。

template<typename T> T bitrot(T& t,size_t bits) { 
    bits %= (sizeof(T)*CHAR_BIT); 
    return ((t >> (sizeof(T)*CHAR_BIT)-bits) | (t << bits)); 
} 

爲了澄清,您應該始終避免將操作移位超過變量中的位數;結果依賴於處理器和編譯器。

+0

我認爲水晶是問如果旋轉更然後在INT位的數量會發生什麼。 因此,在你的bitrot()函數的開頭放: bits = bits%(sizeof(T)* CHAR_BITS); – dkantowitz 2010-01-19 23:59:17

+0

事實上,移位必須小於*類型的寬度,所以當位數= 0時,實際上在上面出現問題。通常不會表現出:n >> 32在pentiums上相當於n >> 0,因此'|'隱藏它。在我看來,在原來的K&R(我丟失了我的副本)中,允許換檔<=寬度,但是新的換算必須是<寬度。任何人都有舊的K&R?我很好奇,因爲intel的第一個變量移位操作(在80186上)查看了5個lbsbs的CL,因此16位值的移位工作從0到16位。隨着386他們留下了5位32位regs。英特爾是否因此破壞C? – greggo 2011-08-24 22:27:34

0

怎麼樣:

union hack { 
    int asSigned; 
    unsigned asUnsigned; 
}; 
hack top, bottom; 
int realBitCount = count % (sizeof(T)*8); 
top.asSigned = (realBitCount == 0) ? 0 : -(1 << (realBitCount-1)); 
bottom.asUnsigned = 0xFFFFFFFF^top.asUnsigned; 

top.asUnsigned &= object; 
bottom.asUnsigned &= object; 
return static_cast<T>((bottom.asUnsigned << realBitCount) | (top.asUnsigned >> (sizeof(T)-realBitCount)));