作者bigpigbigpig (To littlepig with love)
看板C_and_CPP
標題Re: [問題] BitSwap
時間Wed Nov 16 13:13:15 2011
※ 引述《kinding (de)》之銘言:
: 請寫一個char Bitswap(char a) function,也就是
: bit0 <-> bit7
: bit1 <-> bit6
: bit2 <-> bit5
: bit3 <-> bit4 ,舉例來說你輸入0x80 則輸出0x01
: 我的想法是用一個char temp[8];每個元素存一個bit
: 所以將原本的char轉成二進位並存入temp
: 然後用reverse,最後再將陣列的元素轉成數值
: 但是這樣的想法感覺很沒有效率,或許查表可以比較快
: 但是這樣一來要建立255個轉換,有人有高見嗎?
0001 | 1000 = 24
0010 | 0100 = 36
0100 | 0010 = 66
1000 | 0001 = 129
用 Matlab 程式碼說明概念:
function b = bitswap(a)
a = uint8(a);
mask = uint8([ 24 36 66 129 ]);
c = bitand(a,mask);
d = bitxor(c,mask);
e1 = uint8(eq(c,mask)) .* mask;
e2 = uint8(eq(d,mask)) .* mask;
b = sum(d) + sum(e1) - sum(e2);
end
(1) 設定 mask 陣列,其元素為 24 (0x18), 36 (0x24), 66 (0x42), 129 (0x81)
(2) a 與 mask 各元素分別做 bit and (罩除),得到 c
(3) c 與 mask 各元素分別做 bit xor (01 ==> 10, 10 ==> 01),得到 d
(4) 但 11 ==> 00 不正確,因此逐一檢查 c 與 mask 的各元素是否相同,然後
與 mask 點乘,得到 e1
(5) 此外,00 ==> 11 也不正確,因此逐一檢查 d 與 mask 的各元素是否相同,然後
與 mask 點乘,得到 e2
(6) 將 d 與 e1 的所有元素 sum 起來,再減去 e2 所有元素的 sum,即為
bit-swap 後的結果。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.61.252.34
※ 編輯: bigpigbigpig 來自: 61.61.252.34 (11/16 13:15)
推 LPH66:bitxor 連 00 也會變 11 吧... 11/16 13:50
謝謝指正,已修改 :)
※ 編輯: bigpigbigpig 來自: 61.61.252.34 (11/16 14:31)
※ 編輯: bigpigbigpig 來自: 61.61.252.34 (11/16 14:31)
上述方法太複雜了,為保留當初使用 mask 的用意,特貼另一較簡明的版本:
function b = bitswap_2(a)
a = uint8(a);
m = uint8([ 24 36 66 129 ]);
c = bitand(a,m);
b = 0;
for i = 1:4
b = b + swap_2_bit(c(i),m(i));
end
end
function b = swap_2_bit(a,mask)
if ( a == 0 || a == mask )
b = a;
else
b = bitxor(a,mask);
end
end
※ 編輯: bigpigbigpig 來自: 61.61.252.34 (11/16 15:44)
→ xatier:可以將這個 code 翻譯成 C/C++ 嗎? 想研究看看,感謝! 11/16 17:01