常用位運算

2021-05-22 19:48:49 字數 3412 閱讀 9995

檢測乙個無符號數是不為2^n-1(^為冪): x&(x+1)

將最右側0位改為1位: x ¦ (x+1)

二進位制補碼運算公式:

-x = ~x + 1 = ~(x-1)

~x = -x-1

-(~x) = x+1

~(-x) = x-1

x+y = x - ~y - 1 = (x ¦y)+(x&y)

x-y = x + ~y + 1 = (x ¦~y)-(~x&y)

x^y = (x ¦y)-(x&y)

x ¦y = (x&~y)+y

x&y = (~x ¦y)-~x

x==y:    ~(x-y ¦y-x)

x!=y:    x-y ¦y-x

x < y:    (x-y)^((x^y)&((x-y)^x))

x <=y:    (x ¦~y)&((x^y) ¦~(y-x))

x < y:    (~x&y) ¦((~x ¦y)&(x-y))//無符號x,y比較

x <=y:    (~x ¦y)&((x^y) ¦~(y-x))//無符號x,y比較

使用位運算的無分支**:

計算絕對值

int abs( int x )

int y ;

y = x >> 31 ;

return (x^y)-y ;//or: (x+y)^y

符號函式:sign(x) = -1, x <0; 0, x == 0 ; 1, x > 0

int sign(int x)

return (x>>31) ¦ (unsigned(-x))>>31 ;//x=-2^31時失敗(^為冪)

三值比較:cmp(x,y) = -1, x y

int cmp( int x, int y )

return (x>y)-(x-y) ;

doz=x-y, x>=y; 0, x int doz(int x, int y )

int d ;

d = x-y ;

return d & ((~(d^((x^y)&(d^x))))>>31) ;

int max(int x, int y )

int m ;

m = (x-y)>>31 ;

return y & m ¦ x & ~m ;

不使用第三方交換x,y:

1.x ^= y ; y ^= x ; x ^= y ;

2.x = x+y ; y = x-y ; x = x-y ;

3.x = x-y ; y = y+x ; x = y-x ;

4.x = y-x ; x = y-x ; x = x+y ;

雙值交換:x = a, x==b; b, x==a//常規編碼為x = x==a ? b :a ;

1.x = a+b-x ;

2.x = a^b^x ;

下捨入到2的k次方的倍數:

1.x & ((-1) < 2.(((unsigned)x)>>k) < 上捨入:

1. t = (1 < 2.t = (-1) < 位計數,統計1位的數量:

1.int pop(unsigned x)

x = x-((x>>1)&0x55555555) ;

x = (x&0x33333333) + ((x>>2) & 0x33333333 ) ;

x = (x+(x>>4)) & 0x0f0f0f0f ;

x = x + (x>>8) ;

x = x + (x>>16) ;

return x & 0x0000003f ;

2.int pop(unsigned x) ;

return table[x&0xff]+table[(x>>8)&0xff]+table[(x>>16)&0xff]+table[(x>>24)] ;

奇偶性計算:

x = x ^ ( x>>1 ) ;

x = x ^ ( x>>2 ) ;

x = x ^ ( x>>4 ) ;

x = x ^ ( x>>8 ) ;

x = x ^ ( x>>16 ) ;

結果中位於x最低位,對無符號x,結果的第i位是原數第i位到最左側位的奇偶性

位反**

unsigned rev(unsigned x)

x = (x & 0x55555555) < < 1 ¦ (x>>1) & 0x55555555 ;

x = (x & 0x33333333) < < 2 ¦ (x>>2) & 0x33333333 ;

x = (x & 0x0f0f0f0f) < < 4 ¦ (x>>4) & 0x0f0f0f0f ;

x = (x < <24) ¦ ((x&0xff00) < <8) ¦ ((x>>8) & 0xff00) ¦ (x>>24) ;

return x ;

遞增位反轉後的數:

unsigned inc_r(unsigned x)

unsigned m = 0x80000000 ;

x ^= m ;

if( (int)x >= 0 )

do while( x < m ) ;

return x ;

混選位:

abcd efgh ijkl mnop abcd efgh ijkl mnop->aabb ccdd eeff gghh iijj kkll mmnn oopp

unsigned ps(unsigned x)

unsigned t ;

t = (x ^ (x>>8)) & 0x0000ff00; x = x ^ t ^ (t < <8) ;

t = (x ^ (x>>4)) & 0x00f000f0; x = x ^ t ^ (t < <4) ;

t = (x ^ (x>>2)) & 0x0c0c0c0c; x = x ^ t ^ (t < <2) ;

t = (x ^ (x>>1)) & 0x22222222; x = x ^ t ^ (t < <1) ;

return x ;

位壓縮:

選擇並右移字x中對應於掩碼m的1位的位,如:compress(abcdefgh,01010101)=0000bdfh

compress_left(x,m)操作與此類似,但結果位在左邊: bdfh0000.

unsigned compress(unsigned x, unsigned m)

unsigned mk, mp, mv, t ;

int i ;

x &= m ;

mk = ~m < < 1 ;

for( i = 0 ; i < 5 ; ++i ) ;

unsigned y ;

y = (x&0x7f7f7f7f) + 0x7f7f7f7f ;

y = ~(y ¦x ¦0x7f7f7f7f) ;

return table[y*0x00204081 >> 28] ;//乘法可用移位和加完成

常用的位運算

1 按位與 0 0 0 0 1 0 1 0 0 1 1 1 同時為1則結果為1,否則為0 如3 8 3 00000011 5 00000101 結果為 00000001 2 按位或 0 0 0 0 1 1 1 0 1 1 1 1 兩個數中只要有乙個為1,則結果為1 同時為0 則結果為0 3 異或 兩...

Python 運算(常用的算術運算 位運算)

運算子含義 例項 假設變數 a 10,b 20 除 x除以y b a 輸出結果 2 取模 返回除法的餘數 b a 輸出結果 0 冪 返回x的y次冪 a b 為10的20次方,輸出結果 取整除 返回商的整數部分 向下取整 9 2 4 運算子含義 按位與操作,只有 1 1 為1,其他情況為0。可用於進製...

常用的位運算技巧

位運算是很多演算法優化的基礎和實現的條件,極其重要。理解位運算對於一些演算法及其優化有著非常重要的意義。本篇隨筆講解位運算的一些基本原理和常用的使用技巧。兩個二進位制數進行與 運算,如果對應位都為1則結果為1,否則為0.與運算常常用於二進位制下的取位操作。想要知道二進位制下的某位是否是1,就 上這個...