假設我有:
unsigned int x = 883621;
其中二進制是:
00000000000011010111101110100101
我需要最快的方法來交換兩個最低位:
00000000000011010111101110100110
注意:澄清一下:如果 x 是 7 (0b111),輸出應該仍然是 7。
uj5u.com熱心網友回復:
如果您有幾個位元組的記憶體可用,我將從查找表開始:
constexpr unsigned int table[]={0b00,0b10,0b01,0b11};
unsigned int func(unsigned int x){
auto y = (x & (~0b11)) |( table[x&0b11]);
return y;
}
-O3到目前為止所有答案的Quickbench。
-Ofast到目前為止所有答案的Quickbench。
(加上我ifelse天真的想法。)
[隨意添加自己并編輯我的問題]。
如果您認為基準測驗不正確,請糾正我,我不是閱讀匯編的專家。所以希望volatile x防止在回圈之間快取結果。
uj5u.com熱心網友回復:
我會暫時忽略最高位 - 有一個使用乘法的技巧。乘法實際上是一種卷積運算,您可以使用它來混洗位。
特別地,假設兩個低位是AB。將其乘以 0b0101,您將得到 ABAB。您會看到交換的位 BA 是中間位。
因此,x = (x & ~3U) | ((((x&3)*5)>>1)&3)
[編輯] 需要 &3 來去除頂部 A 位,但是使用 std::uint_32_t 您可以使用溢位來免費丟失該位 - 乘法然后得到結果 BAB0'0000'0000'0000'0000'0000'0000 '0000'0000' :
x = (x & ~3U) | ((((x&3)*0xA0000000)>>30));
uj5u.com熱心網友回復:
我會用
x = (x & ~0b11) | ((x & 0b10) >> 1) | ((x & 0b01) << 1);
uj5u.com熱心網友回復:
另一個想法,以避免剝離最高位。假設 x 有 XXXXAB 位,那么我們想要 x 或它與 0000(A^B)(A^B)。因此
auto t = x^(x>>1); // Last bit is now A^B
t &=1; // take just that bit
t *= 3; // Put in the last two positions
x ^= t; // Change A to B and B to A.
uj5u.com熱心網友回復:
受表思想的啟發,但將表作為一個簡單的常量而不是陣列。我們只需要掩碼(00)==00、掩碼(01)==11、掩碼(10)=11、掩碼(11)==11。
constexpr unsigned int table = 0b00111100;
unsigned int func(unsigned int x) {
auto xormask = (table >> ((x&3) * 2)) &3;
x ^= xormask;
return x;
}
這也使用了 dyungwang 的異或技巧來避免隔離最高位。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/339979.html
上一篇:C 結構體的初始化
下一篇:在C 中查找字符陣列的大小
