AImager

C/C++/PHP中的位运算

&   // 与and
|   // 或or
~   // 非not
^   // 异或xor
<<  // 左移位shl
>>  // 右移位shr

swap

定理:互为逆运算的两个操作符可进行特殊交换(swap),即经过以下操作,a,b交换值(oper1与oper2互为逆运算)

a = a oper1 b
b = a oper2 b
a = a oper2 b

推广:异或与自己本身成逆运算,因此将异或带入上面的操作会很怪异,但是很快

常用位运算(C/PHP实现)

// 去掉最后一位
// 例:101101->10110
x >> 1

// 在最后加一个0
// 例:101101->1011010
x << 1

// 在最后加一个1
// 例:101101->1011011
x << 1+1

// 把最后一位变成1
// 例:101100->101101
x | 1

// 把最后一位变成0
// 101101->101100
x | 1-1

// 最后一位取反
// 101101->101100
x ^ 1

// 把右数第k位变成1
// 101001->101101,k=3
x | (1 << (k-1))

// 把右数第k位变成0
// 101101->101001,k=3
x & ~ (1 << (k-1))

// 右数第k位取反
// 101001->101101,k=3
x ^ (1 << (k-1))

// 取末三位
// 1101101->101
x & 7

// 取末k位
// 1101101->1101,k=5
x & (1 << k-1)

// 取右数第k位
// 1101101->1,k=4
x >> (k-1) & 1

// 把末k位变成1
// 101001->101111,k=4
x | (1 << k-1)

// 末k位取反
// 101001->100110,k=4
x ^ (1 << k-1)

// 把右边连续的1变成0
// 100101111->100100000
x & (x+1)

// 把右起第一个0变成1
// 100101111->100111111
x | (x+1)

// 把右边连续的0变成1
// 11011000->11011111
x | (x-1)

// 取右边连续的1
// 100101111->1111
(x ^ (x+1)) >> 1

// 去掉右起第一个1的左边
// 100101000->1000
x & (x ^ (x-1))