優(yōu)秀程序員不得不知道的20個位運算技巧

優(yōu)秀程序員不得不知道的20個位運算技巧

分類:語言2012-12-08 09:4530791人閱讀評論(122)收藏舉報

位運算

目錄(?)[+]

一提起位運算季俩,人們往往想到它的高效性,無論是嵌入式編程還是優(yōu)化系統(tǒng)的核心代碼违寞,適當?shù)倪\用位運算總是一種迷人的手段翎卓,或者當您求職的時候契邀,在代碼中寫入適當?shù)奈贿\算也會讓您的程序增加一絲亮點,最初當我讀《編程之美》求“1的數(shù)目”時失暴,我才開始覺得位運算是如此之美坯门,后來讀到?《Hacker's Delight》,感慨到Henry S.Warren把位運算運用的如此神出鬼沒逗扒,很多程序都十分精妙古戴,我覺得在一個普通的程序中大量運用這樣的代碼的人簡直是瘋了!但掌握簡單的位運算技巧還是必要的矩肩,所以今天寫這篇博文把我積累的一些位運算技巧分享給大家现恼,這些技巧不會是如求“1的數(shù)目”的技巧,是最基本的一行位運算技巧!

Welcome To MyBitTricks

1.獲得int型最大值

[cpp]view plaincopy

intgetMaxInt(){

return(1?<<?31)?-?1;//2147483647叉袍,?由于優(yōu)先級關(guān)系始锚,括號不可省略

}

另一種寫法

[cpp]view plaincopy

intgetMaxInt(){

return~(1?<<?31);//2147483647

}

另一種寫法

[cpp]view plaincopy

intgetMaxInt(){//有些編譯器不適用

return(1?<<?-1)?-?1;//2147483647

}

C語言中不知道int占幾個字節(jié)時候

[java]view plaincopy

intgetMaxInt(){

return((unsignedint)?-1)?>>1;//2147483647

}

2.獲得int型最小值

[cpp]view plaincopy

intgetMinInt(){

return1?<<?31;//-2147483648

}

另一種寫法

[cpp]view plaincopy

intgetMinInt(){//有些編譯器不適用

return1?<<?-1;//-2147483648

}

3.獲得long類型的最大值

C語言版

[cpp]view plaincopy

longgetMaxLong(){

return((unsignedlong)?-?1)?>>?1;//2147483647

}

JAVA版

[java]view plaincopy

longgetMaxLong(){

return((long)1<<127)?-1;//9223372036854775807

}

獲得long最小值,和其他類型的最大值喳逛,最小值同理.

4.乘以2運算

[cpp]view plaincopy

intmulTwo(intn){//計算n*2

returnn?<<?1;

}

5.除以2運算

[cpp]view plaincopy

intdivTwo(intn){//負奇數(shù)的運算不可用

returnn?>>?1;//除以2

}

6.乘以2的m次方

[cpp]view plaincopy

intmulTwoPower(intn,intm){//計算n*(2^m)

returnn?<<?m;

}

7.除以2的m次方

[cpp]view plaincopy

intdivTwoPower(intn,intm){//計算n/(2^m)

returnn?>>?m;

}

8.判斷一個數(shù)的奇偶性

[java]view plaincopy

booleanisOddNumber(intn){

return(n?&1)?==1;

}

9.不用臨時變量交換兩個數(shù)(面試城瓢疲考)

C語言版

[cpp]view plaincopy

voidswap(int*a,int*b){

(*a)?^=?(*b)?^=?(*a)?^=?(*b);

}

通用版(一些語言中得分開寫)

[java]view plaincopy

a?^=?b;

b?^=?a;

a?^=?b;

10.取絕對值(某些機器上,效率比n>0 ?? ?n:-n 高)

[cpp]view plaincopy

intabs(intn){

return(n?^?(n?>>?31))?-?(n?>>?31);

/*?n>>31?取得n的符號润文,若n為正數(shù)姐呐,n>>31等于0,若n為負數(shù)转唉,n>>31等于-1

若n為正數(shù)?n^0=0,數(shù)不變皮钠,若n為負數(shù)有n^-1?需要計算n和-1的補碼,然后進行異或運算赠法,

結(jié)果n變號并且為n的絕對值減1,再減去-1就是絕對值?*/

}

11.取兩個數(shù)的最大值(某些機器上乔夯,效率比a>b ? a:b高)

通用版

[cpp]view plaincopy

intmax(inta,intb){

returnb?&?((a-b)?>>?31)?|?a?&?(~(a-b)?>>?31);

/*如果a>=b,(a-b)>>31為0砖织,否則為-1*/

}

C語言版

[cpp]view plaincopy

intmax(intx,inty){

returnx?^?((x?^?y)?&?-(x?<?y));

/*如果x

、?與0做與運算結(jié)果為0末荐,與-1做與運算結(jié)果不變*/

}

12.取兩個數(shù)的最小值(某些機器上侧纯,效率比a>b ? b:a高)

通用版

[cpp]view plaincopy

intmin(inta,intb){

returna?&?((a-b)?>>?31)?|?b?&?(~(a-b)?>>?31);

/*如果a>=b,(a-b)>>31為0,否則為-1*/

}

C語言版

[cpp]view plaincopy

intmin(intx,inty){

returny?^?((x?^?y)?&?-(x?<?y));

/*如果x

與0做與運算結(jié)果為0甲脏,與-1做與運算結(jié)果不變*/

}

13.判斷符號是否相同

[java]view plaincopy

booleanisSameSign(intx,inty){//有0的情況例外

return(x?^?y)?>=0;//?true?表示?x和y有相同的符號眶熬,?false表示x,y有相反的符號块请。

}

14.計算2的n次方

[cpp]view plaincopy

intgetFactorialofTwo(intn){//n?>?0

return2?<<?(n-1);//2的n次方

}

15.判斷一個數(shù)是不是2的冪

[java]view plaincopy

booleanisFactorialofTwo(intn){

returnn?>0??(n?&?(n?-1))?==0:false;

/*如果是2的冪娜氏,n一定是100...?n-1就是1111....

所以做與運算結(jié)果為0*/

}

16.對2的n次方取余

[java]view plaincopy

intquyu(intm,intn){//n為2的次方

returnm?&?(n?-1);

/*如果是2的冪,n一定是100...?n-1就是1111....

所以做與運算結(jié)果保留m在n范圍的非0的位*/

}

17.求兩個整數(shù)的平均值

[java]view plaincopy

intgetAverage(intx,inty){

return(x?+?y)?>>1;

另一種寫法

[java]view plaincopy

intgetAverage(intx,inty){

return((x?^?y)?>>1)?+?(x?&?y);

/*(x^y)?>>?1得到x墩新,y其中一個為1的位并除以2贸弥,

x&y得到x,y都為1的部分海渊,加一起就是平均數(shù)了*/

}

下面是三個最基本對二進制位的操作

18.從低位到高位,取n的第m位

[java]view plaincopy

intgetBit(intn,intm){

return(n?>>?(m-1))?&1;

}

19.從低位到高位.將n的第m位置1

[java]view plaincopy

intsetBitToOne(intn,intm){

returnn?|?(1<<?(m-1));

/*將1左移m-1位找到第m位绵疲,得到000...1...000

n在和這個數(shù)做或運算*/

}

20.從低位到高位,將n的第m位置0

[java]view plaincopy

intsetBitToZero(intn,intm){

returnn?&?~(1<<?(m-1));

/*?將1左移m-1位找到第m位,取反后變成111...0...1111

n再和這個數(shù)做與運算*/

}

另附一些對程序效率上沒有實質(zhì)提高的位運算技巧臣疑,一些也是位運算的常識(面試也許會遇到)

計算n+1

[cpp]view plaincopy

-~n

計算n-1

[cpp]view plaincopy

~-n

取相反數(shù)

[java]view plaincopy

~n?+1;

另一種寫法

[java]view plaincopy

(n?^?-1)?+1;

if(x == a) x = b; if(x == b) x = a;

[cpp]view plaincopy

x?=?a?^?b?^?x;

sign函數(shù)盔憨,參數(shù)為n,當n>0時候返回1讯沈,n<0時返回-1郁岩,n=0時返回0

[cpp]view plaincopy

return!!n?-?(((unsigned)n?>>?31)?<<?1);

如果您知道實用的一行位運算技巧請留言,博主不勝感激,還有我總結(jié)的位運算難免有不健壯之處驯用,請您多多批評脸秽。

==================================================================================================

作者:nash_ ?歡迎轉(zhuǎn)載,與人分享是進步的源泉蝴乔!

轉(zhuǎn)載請保留原文地址:http://blog.csdn.net/nash_/article/details/8262185

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末记餐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子薇正,更是在濱河造成了極大的恐慌片酝,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挖腰,死亡現(xiàn)場離奇詭異雕沿,居然都是意外死亡,警方通過查閱死者的電腦和手機猴仑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門审轮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人辽俗,你說我怎么就攤上這事疾渣。” “怎么了崖飘?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵榴捡,是天一觀的道長。 經(jīng)常有香客問我朱浴,道長吊圾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任翰蠢,我火速辦了婚禮项乒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘躏筏。我一直安慰自己板丽,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布趁尼。 她就那樣靜靜地躺著埃碱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪酥泞。 梳的紋絲不亂的頭發(fā)上砚殿,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音芝囤,去河邊找鬼似炎。 笑死辛萍,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的羡藐。 我是一名探鬼主播贩毕,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼仆嗦!你這毒婦竟也來了辉阶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤瘩扼,失蹤者是張志新(化名)和其女友劉穎谆甜,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體集绰,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡规辱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了栽燕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罕袋。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖碍岔,靈堂內(nèi)的尸體忽然破棺而出炫贤,到底是詐尸還是另有隱情,我是刑警寧澤付秕,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站侍郭,受9級特大地震影響询吴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜亮元,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一猛计、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧爆捞,春花似錦奉瘤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至成肘,卻和暖如春卖局,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背双霍。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工砚偶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留批销,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓染坯,卻偏偏與公主長得像均芽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子单鹿,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 概述:排序有內(nèi)部排序和外部排序掀宋,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進行排序,而外部排序是因排序的數(shù)據(jù)很大羞反,一次不能容納全部...
    每天刷兩次牙閱讀 3,727評論 0 15
  • 1. 關(guān)于診斷X線機準直器的作用布朦,錯誤的是()。 (6.0 分) A. 顯示照射野 B. 顯示中心線 C. 屏蔽多...
    我們村我最帥閱讀 10,270評論 0 5
  • 最近在寫個性化推薦的論文昼窗,經(jīng)常用到Python來處理數(shù)據(jù)是趴,被pandas和numpy中的數(shù)據(jù)選取和索引問題繞的比較...
    shuhanrainbow閱讀 4,535評論 6 19
  • 這是薛兆豐老師的精品課《透徹了解成本概念》學(xué)完后的總結(jié)唆途。 成本概念是基礎(chǔ)經(jīng)濟學(xué)中很重要的概念,理解了這個...
    可凡DCT閱讀 979評論 0 0
  • 那個寫在微博上的詞——“將來”掸驱,你說的是還沒有發(fā)生的一個事件肛搬,還是已經(jīng)出發(fā)但卻來不及抵達的時間?醫(yī)學(xué)專家說:疾病從...
    陳子弘閱讀 666評論 1 8