次の 2 つの数値があるとします。
x = 0xB7
y = 0xD9
それらのバイナリ表現は次のとおりです。
x = 1011 0111
y = 1101 1001
ここで、特定のポイント、たとえばポジション 4 以降でクロスオーバー (GA) したいと考えています。
期待される結果は次のとおりです。
x = 1011 1001
y = 1101 0111
ビットごとに、どうすればこれを達成できますか?
次の 2 つの数値があるとします。
x = 0xB7
y = 0xD9
それらのバイナリ表現は次のとおりです。
x = 1011 0111
y = 1101 1001
ここで、特定のポイント、たとえばポジション 4 以降でクロスオーバー (GA) したいと考えています。
期待される結果は次のとおりです。
x = 1011 1001
y = 1101 0111
ビットごとに、どうすればこれを達成できますか?
ビット単位の演算子を使用します。
t = (x & 0x0f)
x = (x & 0xf0) | (y & 0x0f)
y = (y & 0xf0) | t
それはその特定のケースでうまくいくでしょう。より適応性を高めるために、次のような関数に入れます (疑似コード、 with &
、ビット単位の「and」、「or」、および「not」をそれぞれ表す) |
:!
def swapBits (x, y, s, e):
lookup = [255,127,63,31,15,7,3,1]
mask = lookup[s] & !lookup[e]
t = x & mask
x = (x & !mask) | (y & mask)
y = (y & !mask) | t
return (x,y)
ルックアップ値を使用すると、スワップするビットを指定できます。2 の開始ビットと 6 の終了ビットと共に yの値とy の値xxxxxxxx
を取得しましょう(このシナリオでは、左側のビット番号はゼロから始まります)。x
yyyyyyyy
s
e
x y s e t mask !mask execute
-------- -------- - - -------- -------- -------- -------
xxxxxxxx yyyyyyyy 2 6 starting point
00111111 mask = lookup[2](00111111)
00111100 & !lookup[6](11111100)
00xxxx00 t = x & mask
xx0000xx x = x & !mask(11000011)
xxyyyyxx | y & mask(00111100)
yy0000yy y = y & !mask(11000011)
yyxxxxyy | t(00xxxx00)
unsigned int i, j; // positions of bit sequences to swap
unsigned int n; // number of consecutive bits in each sequence
unsigned int b; // bits to swap reside in b
unsigned int r; // bit-swapped result goes here
unsigned int x = ((b >> i) ^ (b >> j)) & ((1U << n) - 1); // XOR temporary
r = b ^ ((x << i) | (x << j));