乙個無符號的整數,如果需要翻轉其二進位制位,可以採用下面的方法,以32位整數為例:
unsigned int v; // 32-bit word to reverse bit order// swap odd and even bits
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
// swap consecutive pairs
v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
// swap nibbles ...
v = ((v >> 4) & 0x0f0f0f0f) | ((v & 0x0f0f0f0f) << 4);
// swap bytes
v = ((v >> 8) & 0x00ff00ff) | ((v & 0x00ff00ff) << 8);
// swap 2-byte long pairs
v = ( v >> 16 ) | ( v << 16);
第1步:對調相鄰的1位(abcd efgh-> badc fehg)
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555)<< 1);
第2步:對調相鄰的2位(abcd efgh-> cdab ghef)
v = ((v >> 4) & 0x0f0f0f0f) | ((v & 0x0f0f0f0f) << 4);
第3步:對調相鄰的4位(abcd efgh-> efgh abcd)
v = ((v >> 4) & 0x0f0f0f0f) | ((v & 0x0f0f0f0f) << 4);
第4步:對調相鄰的8位(相鄰的位元組)
v = ((v >> 8) & 0x00ff00ff) | ((v & 0x00ff00ff) << 8);
第5步:對調相鄰的16位(相鄰的兩位元組)
v = ( v >> 16 ) | ( v << 16);
經過上面的步驟,乙個32位整數的二進位制位已經翻轉了。上面的對調步驟是互不干擾的,因此順序可以倒過來,也就是先對調相鄰16位,然後是8位、4位、2位和1位。所以,有人發明了下面的演算法:
unsigned int s = sizeof(v) * char_bit; // bit size; must be power of 2unsigned int mask = ~0;
while ((s >>= 1) > 0)
上面**中,每次mask計算得到的值分別是:0x0000ffff、0x00ff00ff、0x0f0f0f0f、0x33333333和0x55555555。而且,經過測試,針對上面的s和mask,((v << s) & ~mask)與((v & mask)<< s)是相同的。所以,上面的演算法,就是最開始介紹的演算法。
這種演算法的時間複雜度為o(lg(n))。比較適合n比較大的情況,redis中,針對64位的實現如下:
unsigned long rev(unsigned long v)return v;
}
二進位制位的翻轉函式
編寫函式 unsigned int reverse bit unsigned int value 這個函式的返回值是value的二進位制位模式從左到右翻轉後的值。如 在32位機器上25這個值包含下列各位 00000000000000000000000000011001 翻轉後 2550136832 ...
二進位制翻轉
編寫函式 unsigned int reverse bit unsigned int value 這個函式的返回值是value的二進位制位模式從左到右翻轉後的值。如 在32位機器上25這個值包含下列各位 00000000000000000000000000011001 翻轉後 2550136832 ...
二進位制翻轉
有的時候我們為了方便對於低位進行操作,我們要把二進位制數翻轉過來,這樣可以避免使用大量的取模操作。直接入正題 我們要求 0,2 的區間中的每乙個翻轉。首先要知道的是什麼叫乙個 a 進製數的翻轉。我們以 2 進製為例,x x x x 它的翻轉就是 rev x x x x x x x x 我們考慮線性求...