2014-03-31 184 views
0

我試圖應用n位的圓形位位移ç循環移位64位使用< <和>>運算符(1和62之間變化),但其結果是不出來按預期.. 。工作不正常

它用1個圓形的變化,但不多(我沒有驗證所有的)...

uint64_t array[25]; 
for(i=0;...) 
    array[i] = ((s[n] << n) | (s[i] >> (64-n))); 

例效果很好: --->竟將這一點:00: 00:02:26:00:00:00:2D --->我得到這個:00:80:80:09:00:00:40:0B

這是沒有任何意義的,因爲我甚至無法理解發生了什麼。

任何幫助,將不勝感激。我試圖做這32位計算機上...也許這有事情做與...

非常感謝;)

+1

我們不知道所有變量的類型,我覺得傾向於猜測。至少你應該把它包裝在一個函數中,並展示整個函數。當然,我們不需要看到長度爲25的數組來處理這個問題。 SSCCE如何? –

+0

是的,請給我們一個例子的小函數,你期望輸入和輸出是什麼? – Salgar

回答

0

確保類型的*s無符號否則你會得到符號擴展的位移。您也可以使用s[n] << n而不是s[i] << n

此外,如果您是在X86-64你可能要考慮使用的處理器指令:

uint64_t temp = s[i]; 
asm ("rolq %0, %%cl" 
    , "+r" (temp) 
    : "c" ((uint8_t)n)); 
array[i] = temp; 
+0

你是對的,但使用內聯彙編在這裏有點矯枉過正。編譯器將優化你的東西(實際上將它翻譯成ROL或ROR指令)。此外,它使代碼不可讀取,更好地堅持<< | >>行,並添加一些評論。 –

+0

你並不需要那麼做,GCC認識到旋轉模式,併發出和實際的'rol'(Clang和ICC也是如此)。我不知道MSVC,但它不喜歡GCC風格的內聯asm,所以這對此無濟於事。 – harold

0

您應該始終如一地使用索引變量對指數和移位計數轉移。然後事情可能會解決。

2

使用S [I],而不是S [N]:

uint64_t array[25]; 
for(i=0;...) 
    array[i] = ((s[i] << n) | (s[i] >> (64-n))); 

您索引變量混合在一起i和移位跨度n的意義不大在此上下文中。我假設s是:

uint64_t s[25]; 

不,這不是一個架構問題... uint64_t中既是在x86和IA64家庭無符號的64位整數。在後者的64位整數由CPU本地處理,在前者中你必須使用更多的寄存器來做同樣的事情......