JAVA 位運算

計算機和真實生活中不同汗菜,一個數(shù)在計算機中只能以二進制(0或者1)的方式表示添诉,現(xiàn)實生活中主要以十進制表示梢褐,在二進制的標示中旺遮,最高位是符號位,最高位如果為0 盈咳,則表示該數(shù)的十進制表示為正數(shù)耿眉,如果最高位為1,則該數(shù)位負數(shù)鱼响。以十進制3為例鸣剪,改為8位的二進制,則是[0000 0011],如果是-3轉(zhuǎn)換為8位的二進制是[1000 0011].在這里[0000 0011] 與3表示的意思相同 ,不過[0000 0011] 是機器數(shù)丈积,3為真值筐骇。

原碼, 反碼, 補碼的基礎(chǔ)概念

1. 原碼

原碼:是最簡單的機器數(shù)表示法。用最高位表示符號位桶癣,‘1’表示負號拥褂,‘0’表示正號。其他位存放該數(shù)的二進制的絕對值牙寞。

若以1000? 0010 為例子

最高位為‘1’,表示這是一個負數(shù)饺鹃,其他七位為‘000? 0010’

即(0*2^7)+(0*2^6)+(0*2^5)+(0*2^4)+(0*2^3)+(0*2^2)+(1*2^1)+(0*2^0)=2(‘^’表示冪運算符)

所以1000? 0010 是-2

2.反碼

反碼:正數(shù)的反碼還是等于原碼

負數(shù)的反碼就是他的原碼除符號位外莫秆,按位取反

若以帶符號位的八位二進制數(shù)為例:

3是正數(shù),反碼與原碼相同悔详,則可以表示為0000 0011

-3的原碼是1000 0011镊屎,符號位保持不變,低七位(000 0011)按位取反得(100? 1100)

3.補碼

補碼:正數(shù)的補碼等于他的原碼

負數(shù)的補碼等于反碼+1茄螃。

(這只是一種算補碼的方式缝驳,多數(shù)書對于補碼就是這句話)

前言

日常開發(fā)中位運算不是很常用,但是巧妙的使用位運算可以大量減少運行開銷归苍,優(yōu)化算法用狱。舉個例子,翻轉(zhuǎn)操作比較常見拼弃,比如初始值為1夏伊,操作一次變?yōu)?,再操作一次變?yōu)?吻氧∧缬牵可能的做法是使用三木運算符,判斷原始值為1還是0盯孙,如果是1鲁森,設(shè)置為0,否則設(shè)置為0.但是使用位運算振惰,不用判斷原始值歌溉,直接改變值就可以。當然骑晶,一條語句可能對代碼沒什么影響研底,但是在高重復,大數(shù)據(jù)量的情況下將會節(jié)省很多開銷透罢。

位運算符

一些只需要一個操作數(shù)的運算符稱為一元運算符(或單目運算符)。

二元運算是由兩個元素形成第三個元素的一種規(guī)則冠蒋。例如數(shù)的加法乘法;更一般地,由兩個集合形成第三個集合的產(chǎn)生方法或構(gòu)成規(guī)則稱為二次運算羽圃。(或雙目運算符)

位邏輯運算符

位邏輯運算符包含 4 個:&(與)、|(或)抖剿、~(非)和 ^(異或)朽寞。除了 ~(即位取反)為單目運算符外,其余都為雙目運算符斩郎。表 1 中列出了它們的基本用法脑融。

位與運算符

位與運算符為&,其運算規(guī)則是:參與運算的數(shù)字缩宜,低位對齊肘迎,高位不足的補零甥温,如果對應(yīng)的二進制位同時為 1,那么計算結(jié)果才為 1妓布,否則為 0姻蚓。因此,任何數(shù)與 0 進行按位與運算匣沼,其結(jié)果都為 0狰挡。

例如下面的表達式:100&0

0110 0100? ---> 100

&0000 0000 --->? 0

? 0000 0000 --->? 0

代碼實現(xiàn):

? ? ? int x = 100,y = 0;

? ? ? int z = x&y;

? ? ? System.out.println("運算結(jié)果:"+z);

//運算結(jié)果:0

位或運算符

位或運算符為|,其運算規(guī)則是:參與運算的數(shù)字释涛,低位對齊加叁,高位不足的補零。如果對應(yīng)的二進制位只要有一個為 1唇撬,那么結(jié)果就為 1它匕;如果對應(yīng)的二進制位都為 0,結(jié)果才為 0局荚。

下面是一個使用位或運算符的表達式:4|7

0000 0100--->4

|? ? 0000 0111--->7

? ? 0000 0111--->7

代碼驗證:

? int x = 4,y = 7;

? ? ? int z = x|y;

? ? ? System.out.println("運算結(jié)果:"+z);

//運算結(jié)果:7

位異或運算符

位異或運算符為^超凳,其運算規(guī)則是:參與運算的數(shù)字,低位對齊耀态,高位不足的補零轮傍,如果對應(yīng)的二進制位相同(同時為 0 或同時為 1)時,結(jié)果為 0首装;如果對應(yīng)的二進制位不相同创夜,結(jié)果則為 1

下面是一個使用位異或運算符的表達式:4^7

0000 0100--->4

^? 0000 0111--->7

? ? 0000 0011--->3

代碼驗證:

? ? ? int x = 4,y = 7;

? ? ? int z = x^y;

? ? ? System.out.println("運算結(jié)果:"+z);

//運算結(jié)果:3

位取反運算符

位取反運算符為~,其運算規(guī)則是:只對一個操作數(shù)進行運算仙逻,將操作數(shù)二進制中的 1 改為 0驰吓,0 改為 1。

下面是一個使用位取反運算符的表達式: ~5

位移運算符

位移運算符用來將操作數(shù)向某個方向(向左或者右)移動指定的二進制位數(shù)系奉。表 2 列出了 Java 語言中的兩個位移運算符檬贰,它們都屬于雙目運算符。

左位移運算符

左移位運算符為?缺亮,其運算規(guī)則是:按二進制形式把所有的數(shù)字向左移動對應(yīng)的位數(shù)翁涤,高位移出(舍棄),低位的空位補零萌踱。

例如葵礼,將整數(shù) 7向左位移 1 位的過程如下:

? ? ? ? ? ? ? ? 0000 0111

? ? ? ? ? ? ? ? 00000 1110---->14

原來數(shù)的所有二進制位都向左移動 1 位。原來位于左邊的最高位 0 被移出舍棄并鸵,再向尾部追加 0 補位鸳粉。最終到的結(jié)果是14,相當于原來數(shù)的 2 倍园担。

代碼驗證:

? ? ? int x = 7;

? ? ? int z = x <<1;

? ? ? System.out.println("運算結(jié)果:"+z);

? ? ? //運算結(jié)果:14

右位移運算符

右位移運算符為?届谈,其運算規(guī)則是:按二進制形式把所有的數(shù)字向右移動對應(yīng)的位數(shù)枯夜,低位移出(舍棄),高位的空位補零疼约。

例如卤档,將整數(shù) 7向右位移 1 位的過程如下:

? ? ? ? ? ? ? ? ? ? ? ? 0000 0111

0000 00111---->3

原來數(shù)的所有二進制位都向右移動 1 位。原來位于右邊的最低位 1 被移出舍棄程剥,再向最高位追加 0 補位劝枣。最終到的結(jié)果是 3,相當于原數(shù)整除 2 余數(shù)舍棄的結(jié)果织鲸。

復合位賦值運算符

所有的二進制位運算符都有一種將賦值與位運算組合在一起的簡寫形式舔腾。復合位賦值運算符由賦值運算符與位邏輯運算符和位移運算符組合而成。表 3 列出了組合后的復合位賦值運算符搂擦。

? int a = 1;

? ? ? int b = 2;

? ? ? int c = 3;

? ? ? a &= 4;

? ? ? a |= 4;

? ? ? a ^= c;

? ? ? a -= 6;

? ? ? b >>= 1;

? ? ? c <<= 1;

? ? ? System.out.println("a = " + a);

? ? ? System.out.println("b = " + b);

? ? ? System.out.println("c = " + c);

????????a = 1

????????b = 1

????????c = 6

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末稳诚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瀑踢,更是在濱河造成了極大的恐慌扳还,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件橱夭,死亡現(xiàn)場離奇詭異氨距,居然都是意外死亡,警方通過查閱死者的電腦和手機棘劣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門俏让,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人茬暇,你說我怎么就攤上這事首昔。” “怎么了糙俗?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵勒奇,是天一觀的道長。 經(jīng)常有香客問我巧骚,道長撬陵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任网缝,我火速辦了婚禮,結(jié)果婚禮上蟋定,老公的妹妹穿的比我還像新娘粉臊。我一直安慰自己,他們只是感情好驶兜,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布扼仲。 她就那樣靜靜地躺著远寸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪屠凶。 梳的紋絲不亂的頭發(fā)上驰后,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機與錄音矗愧,去河邊找鬼灶芝。 笑死,一個胖子當著我的面吹牛唉韭,可吹牛的內(nèi)容都是我干的夜涕。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼属愤,長吁一口氣:“原來是場噩夢啊……” “哼女器!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起住诸,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤驾胆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后贱呐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丧诺,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年吼句,在試婚紗的時候發(fā)現(xiàn)自己被綠了锅必。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡惕艳,死狀恐怖搞隐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情远搪,我是刑警寧澤劣纲,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站谁鳍,受9級特大地震影響癞季,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜倘潜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一绷柒、第九天 我趴在偏房一處隱蔽的房頂上張望留美。 院中可真熱鬧幔摸,春花似錦、人聲如沸甲馋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奈应。三九已至,卻和暖如春购披,著一層夾襖步出監(jiān)牢的瞬間杖挣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工刚陡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惩妇,地道東北人。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓橘荠,卻偏偏與公主長得像屿附,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子哥童,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351