很多編程語言都有位運(yùn)算符,Java語言也不例外。在Java語言中,提供了7種位運(yùn)算符,分別是按位與(&)、按位或(|)、按位異或(^)、取反(~)、左移(<<)、帶符號右移(>>)和無符號右移(>>>)。這些運(yùn)算符當(dāng)中,僅有~是單目運(yùn)算符,其他運(yùn)算符均為雙目運(yùn)算符。在講解這些運(yùn)算符的使用之前,必須了解一個常識,那就是:位運(yùn)算符是對long、int、short、byte和char這5種類型的數(shù)據(jù)進(jìn)行運(yùn)算的,我們不能對double、float和boolean進(jìn)行位運(yùn)算操作。下面就來詳細(xì)講解這7種位運(yùn)算符的使用方法。
成都創(chuàng)新互聯(lián)專注于湖州企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站,購物商城網(wǎng)站建設(shè)。湖州網(wǎng)站建設(shè)公司,為湖州等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站開發(fā),專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)按位與運(yùn)算符的寫法是一個”&”符號,與”不短路的邏輯與運(yùn)算符”寫法是完全一樣的,但意義不同。邏輯與運(yùn)算是對布爾型數(shù)據(jù)進(jìn)行運(yùn)算,而按位與運(yùn)算是對二進(jìn)制位上的數(shù)值進(jìn)行計(jì)算。按位與運(yùn)算符的運(yùn)算規(guī)則如下圖所示:
運(yùn)算規(guī)則總結(jié)成一句話就是:如果兩個二進(jìn)制位上的數(shù)都是1,那么運(yùn)算結(jié)果為1,其他情況運(yùn)算結(jié)果均為0。下面舉例說明按位與運(yùn)算符的運(yùn)算過程,我們用數(shù)字5和6進(jìn)行按位與運(yùn)算。這個過程可以用下圖表示:
運(yùn)算過程中,首先把5和6這兩個數(shù)字轉(zhuǎn)換為補(bǔ)碼,之后還要把這兩個數(shù)字按位對齊,然后一一把兩個相應(yīng)的二進(jìn)制位上的數(shù)字進(jìn)行按位與運(yùn)算,運(yùn)算得到的二進(jìn)制串就是最終的結(jié)果。按照補(bǔ)碼反向轉(zhuǎn)換為十進(jìn)制數(shù)字的規(guī)則,可以計(jì)算出5&6的運(yùn)算結(jié)果是4。在這里要提醒大家一句:進(jìn)行位運(yùn)算的時候,最左邊的符號位也是要參與運(yùn)算的。
按位或運(yùn)算符的寫法是一個”|”符號,與”不短路的邏輯或運(yùn)算符”寫法相同,它的運(yùn)算規(guī)則也很簡單,如下圖所示:
運(yùn)算規(guī)則概括成比較好記的一句話就是:兩個二進(jìn)制位上的數(shù)字如果都為0,那么運(yùn)算結(jié)果為0,否則運(yùn)算結(jié)果是1。同按位與運(yùn)算一樣,符號位也要參與運(yùn)算。下面我們還是用5和6為例來講解一下按位或的運(yùn)算過程,如下圖所示:
首先還是把這兩個數(shù)字轉(zhuǎn)換成補(bǔ)碼形式,之后把相應(yīng)的二進(jìn)制位上的數(shù)字進(jìn)行按位或運(yùn)算:如果兩個二進(jìn)制數(shù)都是0,計(jì)算結(jié)果為0,其他情況計(jì)算結(jié)果均為1。按照這個規(guī)則把每一位上的數(shù)字都計(jì)算一遍后,得到二進(jìn)制的運(yùn)算結(jié)果是111,這個運(yùn)算結(jié)果轉(zhuǎn)換為十進(jìn)制數(shù)是7。
按位異或運(yùn)算符寫法是”^”,它的運(yùn)算規(guī)則如下圖:
如上圖,運(yùn)算規(guī)則為:兩個二進(jìn)制位上的數(shù)字如果相同,則運(yùn)算結(jié)果為0,如果兩個二進(jìn)制位上的數(shù)字不相同,則運(yùn)算結(jié)果為1。下面我們還是用5和6為例來講解一下異或的運(yùn)算過程,如下圖:
首先還是把這兩個數(shù)字轉(zhuǎn)換成補(bǔ)碼形式,之后把相應(yīng)的二進(jìn)制位上的數(shù)字進(jìn)行異或運(yùn)算,如果對應(yīng)的兩個二進(jìn)制位上的數(shù)相同,計(jì)算結(jié)果為0,否則計(jì)算結(jié)果為1。按照這個規(guī)則把每一位上的數(shù)字都計(jì)算一遍后,得到二進(jìn)制的運(yùn)算結(jié)果是11,這個運(yùn)算結(jié)果轉(zhuǎn)換為十進(jìn)制數(shù)是3。
關(guān)于異或運(yùn)算符,有很多非常有用的特性,我們在這里梳理總結(jié)一下。
Ⅰ、異或運(yùn)算符滿足交換律
也就是說,a^b與b^a是等價的,雖然a和b交換了位置,但還是會運(yùn)算出相同的結(jié)果。這個規(guī)律還可以推廣到N個操作數(shù),也就是說,如果有N個變量都參與了異或運(yùn)算,那么它們的位置無論如何交換,運(yùn)算的結(jié)果都是相同的。
Ⅱ、任何兩個相同的數(shù)字進(jìn)行異或操作,所得到的結(jié)果都必然為0
這個特性并不難理解,因?yàn)閮蓚€相同的數(shù)字,換算成補(bǔ)碼后,每個二進(jìn)制位上的數(shù)也都相同,這樣在進(jìn)行異或運(yùn)算時,按照運(yùn)算規(guī)則,每個二進(jìn)制位上得到的運(yùn)算結(jié)果也都是0,這N個0所組成的二進(jìn)制串就是數(shù)字0的補(bǔ)碼。我們可以利用這個特性快速的判斷兩個整數(shù)是否相同。另外,利用這個特性還可以實(shí)現(xiàn)內(nèi)存的快速清零操作,比如我們可以在代碼中寫上a=a^a;這條語句能快速的把變量a所占據(jù)的那幾個字節(jié)的內(nèi)存迅速清零。
Ⅲ、對于任意一個二進(jìn)制位來說,這個位上的數(shù)與0進(jìn)行異或運(yùn)算,運(yùn)算結(jié)果與這個二進(jìn)制位上的數(shù)是相同的,而與1進(jìn)行異或運(yùn)算,結(jié)果與這個二進(jìn)制位上的數(shù)字相反
注意,我們現(xiàn)在說的是二進(jìn)制位上的數(shù)字,所謂相反不是說原來這個位上是1,運(yùn)算結(jié)果是-1,而是說原來是1,運(yùn)算結(jié)果為0,原來如果是0,運(yùn)算結(jié)果是1,這才是此處所說的”相反”的概念。這個特性也非常好理解,小伙伴們一定要記住它,在以后進(jìn)行一些位運(yùn)算操作的時候經(jīng)常會用到這個特性。
Ⅳ、對于任何兩個整數(shù)a和b,a^b^b等于a
這個結(jié)論為什么成立呢?簡單說來,就是因?yàn)檫@個表達(dá)式中有b^b,而b^b的結(jié)果為0,前文已講過,任何一個數(shù)與0進(jìn)行按位異或操作,結(jié)果仍然是這個數(shù)本身,所以,a^b^b等于a。這個特性在加密運(yùn)算方面有著很普遍的應(yīng)用。我們可以把a(bǔ)當(dāng)作要加密的數(shù)據(jù),而把b當(dāng)作密鑰。a異或b就是把a(bǔ)用密鑰b進(jìn)行了加密操作,當(dāng)需要解密時,仍然以b作為密鑰,再進(jìn)行一次異或就實(shí)現(xiàn)了解密。
這個特性還可以推出另外一個結(jié)論:對于任何兩個整數(shù)a和b,a^b^a等于b。我們能夠得到這個結(jié)論的原因也很簡單,就是因?yàn)榘凑战粨Q律,a^b與b^a的運(yùn)算結(jié)果是一樣的,所以a^b^a等價于b^a^a,這個表達(dá)式中出現(xiàn)了a^a,a^a的值也為0,所以整個表達(dá)式的其實(shí)就相當(dāng)于b^0,最終結(jié)果還是b。
希望大家能夠牢記以上這些結(jié)論,在后續(xù)的文章中,會講解如何用這些結(jié)論去解決實(shí)際問題。
按位取反運(yùn)算符寫法是”~”,它的運(yùn)算規(guī)則是:對每個二進(jìn)制位進(jìn)行取反操作,所謂取反就是原來二進(jìn)制位上如果是0,那么就變成1,反之,如果原來二進(jìn)制位上是1,那么就變?yōu)?。取反運(yùn)算符是一個單目運(yùn)算符,所以只需要一個操作數(shù)就可以了。我們以數(shù)字5為例講解按位取反的運(yùn)算過程:
首先把數(shù)字5轉(zhuǎn)換成補(bǔ)碼形式,之后把每個二進(jìn)制位上的數(shù)字進(jìn)行取反,如果是0就變成1,如果1就變成0,經(jīng)過取反后得到的二進(jìn)制串就是運(yùn)算結(jié)果,這個運(yùn)算結(jié)果被還原為十進(jìn)制數(shù)是-6。取反運(yùn)算符的運(yùn)算規(guī)則也非常容易理解,但是在這里老師需要提醒各位讀者注意:如果是對變量進(jìn)行取反操作,那么經(jīng)過操作之后,變量的值并不會發(fā)生變化!為方便小伙伴們理解,請看下圖:
從程序運(yùn)行的結(jié)果可以看出:輸出a的值還是5,這說明變量a經(jīng)過取反得到的那個-6并沒有被賦值到變量a中,通過這個例子可以證明,取反運(yùn)算并沒有對變量重新賦值的功能,取反運(yùn)算的結(jié)果只是臨時保存在操作數(shù)棧中,變量本身的值不會因取反操作而發(fā)生改變。
下面再來講解一下與位移相關(guān)的運(yùn)算符。所謂”位移”就是指在內(nèi)存中對二進(jìn)制串進(jìn)行移動的操作。只要是移動操作,就必然會涉及到以下幾個問題,怎樣表示移動方向?怎樣表示移動的位數(shù)?移動之后空出來的二進(jìn)制位用什么來填充?移動之后跑到原來內(nèi)存單元外面的那些數(shù)字怎么處理?符號位要不要跟著一起移動?這些問題都是我們學(xué)習(xí)位移操作要弄清楚的細(xì)節(jié)。各位小伙伴可以帶著這些問題來學(xué)習(xí)位移相關(guān)的運(yùn)算符。與位移相關(guān)的運(yùn)算符有三個,分別是左移(<<)、帶符號右移(>>)、無符號右移(>>>)。
左移運(yùn)算符的寫法是”<<“,看上去向兩個向左的箭頭,表示要把二進(jìn)制數(shù)據(jù)在內(nèi)存空間中向左邊移動。使用左移運(yùn)算符時,把想進(jìn)行位移操作的操作數(shù)放最左面,之后寫上左移運(yùn)算符,在左移運(yùn)算符的右邊寫上移動的位數(shù)。例如:"5<<2"就表示對數(shù)字5進(jìn)行左移2位的操作。下圖展示了進(jìn)行左移操作之后,二進(jìn)制串在內(nèi)存中是怎樣變化的:
可以看到這個二進(jìn)制串在內(nèi)存中整體向左移動了兩位,那么最左邊的兩位就跑到內(nèi)存單元的外面去了,這兩位數(shù)字將會被舍棄,右邊空出的兩位用0補(bǔ)齊。
左移運(yùn)算有乘以2的N次方的效果。一個數(shù)向左移動1位,就相當(dāng)于乘以2的1次方,移動兩位就相當(dāng)于乘以2的2次方,也就是乘以4。位移操作在實(shí)際運(yùn)算時遠(yuǎn)遠(yuǎn)快于乘法操作,所以在某些對運(yùn)算速度要求非常高的場合,可以考慮用左移代替乘以2的N次方的乘法操作。但是需要提醒大家注意三個細(xì)節(jié):
首先:位移操作同取反操作一樣,并不能改變變量本身的值,所能改變的僅是存儲在操作數(shù)棧中那個數(shù)據(jù)的值,不理解這句話意思的小伙伴看下圖:
其次:當(dāng)位移的位數(shù)很多時,導(dǎo)致最左邊的符號位發(fā)生變化,就不再具有乘以2的N次方的效果了。比如十進(jìn)制的5轉(zhuǎn)換為補(bǔ)碼形式是:前面29個0最后3位是101,如果移動29位,那么最前面的符號位就變成了1,此時運(yùn)算的結(jié)果就成為了一個負(fù)數(shù),不再是5乘以2的29次方的乘法結(jié)果。
最后:對于byte/short/int三種類型的數(shù)據(jù),Java語言最多支持31位的位移運(yùn)算,對于long類型的數(shù)據(jù)而言,最多支持63位的位移運(yùn)算。這可能是因?yàn)镴ava語言的設(shè)計(jì)者認(rèn)為位移的偏移量已經(jīng)超過存儲數(shù)據(jù)本身的長度,沒有什么意義。小伙伴們可以試一下數(shù)字5左移32位是什么結(jié)果。
右移運(yùn)算分為兩種,分別是帶符號右移和無符號右移。首先我們來說說帶符號右移運(yùn)算符。帶符號右移運(yùn)算符的寫法是”>>“,與左移運(yùn)算符的方向恰好相反。所謂帶符號右移就是指當(dāng)二進(jìn)制串向右邊移動以后,左邊空出的位用”符號位上的數(shù)字”填充,說的更直白一點(diǎn),如果是正數(shù),二進(jìn)制串右移的時候用0來填充左邊的空位,而對于負(fù)數(shù)而言,右移的時候用1來填充左邊的空位,如下圖:
從圖上可以清楚的看到帶符號右移操作在二進(jìn)制串移動之后左邊空位是怎樣被填充的。之前強(qiáng)調(diào)過,左移操作具有乘以2的N次方的效果,其實(shí)帶符號右移也具有”類似”除以2的N次方的效果。請注意,這里說的是”類似”除以2的N次方的效果,為什么要加上”類似”兩個字呢?就是因?yàn)閷τ谡龜?shù)而言,帶符號右移之后產(chǎn)生的數(shù)字確實(shí)等于除以2的N次方,但是對于負(fù)數(shù)而言,帶符號右移是在除以2的N次方的結(jié)果之上還要減去1。比如對于正5,帶符號右移兩位的結(jié)果是1,而對于-5,帶符號右移兩位的結(jié)果是-2,也就是-5被2的2次方整除再減去1的結(jié)果。
帶符號右移的操作可以保證移動之前和移動之后數(shù)字的正負(fù)屬性不變,原來是正數(shù),不管移動多少位,移動之后還是正數(shù),原來是負(fù)數(shù),移動之后還是負(fù)數(shù)。另外,我們還可以繼續(xù)深挖一下這個特性,從而得到一個結(jié)論:對于任何一個byte、short或者int類型的數(shù)據(jù)而言,帶符號右移31位之后,得到的必然是0或者是-1。對于long類型的數(shù)據(jù)而言,帶符號右移63位之后,得到的也必然是0或者是-1。能夠得出這個結(jié)論的依據(jù)也很簡單,就是因?yàn)閷τ赽yte、short和int類型的變量而言,如果是正數(shù),帶符號右移31位之后產(chǎn)生的二進(jìn)制串必然全部是0,轉(zhuǎn)換成對應(yīng)的十進(jìn)制數(shù)就是0;而對于負(fù)數(shù)而言,帶符號右移31位之后產(chǎn)生的二進(jìn)制串必然全部是1,轉(zhuǎn)換成十進(jìn)制數(shù)就是-1。對于long類型的數(shù)據(jù),帶符號右移63位也具有相同效果。
前文已說過:右移運(yùn)算分為兩種,分別是帶符號右移和無符號右移。現(xiàn)在再來講解無符號右移。無符號右移運(yùn)算符的寫法是”>>>”,比帶符號右移多了一個”>”。帶符號右移的運(yùn)算規(guī)則與無符號右移的運(yùn)算規(guī)則差別就在于:無符號右移在二進(jìn)制串移動之后,空位由0來補(bǔ)充,與符號位是0還是1毫無關(guān)系,如下圖:
更多相關(guān)內(nèi)容:
java中有哪些運(yùn)算符
java運(yùn)算符優(yōu)先級是什么
以上圖片展示了無符號右移的運(yùn)算規(guī)則。對于正數(shù)而言,無符號右移和帶符號右移沒有什么區(qū)別,而對于負(fù)數(shù)而言,經(jīng)過無符號右移會產(chǎn)生一個正數(shù),因?yàn)樽钭筮叺姆栁槐?填充了。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
網(wǎng)頁標(biāo)題:Java中7種位運(yùn)算符的使用方法-創(chuàng)新互聯(lián)
文章來源:http://vcdvsql.cn/article48/jipep.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、品牌網(wǎng)站設(shè)計(jì)、App設(shè)計(jì)、網(wǎng)頁設(shè)計(jì)公司、網(wǎng)站維護(hù)、虛擬主機(jī)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)