基本概念
1、當前常見的CPU位數是32位和64位,所謂32位處理器就是一次只能處理32位,也就是4個字節的數據,而64位處理器一次則能處理64位,即8個字節的數據。
2、一字節(1Byte)等于8位(8bit),位是計算機存儲數據的最小單位,也就是計算存儲的數據是一系列二進制位信息。每個位用0或1表示。(大B和小b的區別需注意哦)
3、為什么一個字節是8位?
現在通用的說法是8位可以涵蓋所有的字符編碼,即ASCII編碼。但歷史上也存在過4位或者7位為1Byte的場景,只是在后續的字符集標準統一中逐漸被8bit所替代。除了歷史原因之外,還有數據存儲的需要(必須要能在一個字節內表示超過100種狀態,包括常用數字,大小寫字母等),再加上早期計算機存儲價格昂貴,所以8bit也是在當時符合二進制特性的必然結果。
4、二進制加減運算,加法:0+0=0,0+1=1,1+0=1,1+1=10 ,逢2進1。
5、二進制轉十進制及十進制轉二進制。
上述列出了一些基本概念和對應的可參考鏈接,建議先優先了解一下。尤其是二進制和十進制的互相轉換以及二進制的加減法規則,在后面都會具體涉及到。
機器數、真值
人類用十進制完全是因為我們有10個手指頭。如果有一天你看到一個外星人,它只有4個手指頭,那么他使用的一定是四進制,如圖所示:
如果能看明白上圖,說明你已經明白了進制和手指頭的關系了。現代的計算機內部使用門電路,它們只能表示0或者1兩個狀態。如果計算機是一個人,那么他只有兩個手指頭,所以它使用二進制。
是的,就是這樣,所謂的進制,實際上并不是什么神秘的東西,只是關于數的一種表示方式而已了。門電路概念
機器數
機器數分為:無符號數和有符號數兩種。
一個數在計算機中的二進制表示形式, 叫做這個數的機器數。機器數是帶符號的,在計算機用一個數的最高位存放符號, 正數為0,負數為1。
比如,十進制中的數 +3 ,計算機字長為8位,轉換成二進制就是00000011。
如果是 -3 ,就是 10000011 。那么,這里的 00000011 和 10000011 就是機器數。
真值
因為第一位是符號位,所以機器數的形式值就不等于真正的數值。
例如上面的有符號數 10000011,其最高位1代表負,其真正數值是 -3 而不是形式值131(10000011轉換成十進制等于131)。
所以,為區別起見,將帶符號位的機器數對應的真正數值稱為機器數的真值。
例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1
原碼、反碼、補碼
為了妥善的處理數據運算過程中符號位的問題,于是就產生了把符號位和數值位一起編碼起來表示相應的數的各種表示方法。例如我們熟悉的原碼、反碼、補碼、移碼等。通常將未經編碼的數稱為真值,編碼后的數稱為機器數或者機器碼。
計算機當前所使用的機器數是采用的補碼的方式。在探求為何機器要使用補碼之前, 讓我們先了解原碼, 反碼和補碼的概念。對于一個數, 計算機要使用一定的編碼方式進行存儲, 原碼, 反碼, 補碼是機器存儲一個具體數字的編碼方式。
原碼
原碼就是符號位加上真值的絕對值, 即用第一位表示符號, 其余位表示值. 比如如果是8位二進制:
[+1]原 = 0000 0001
[-1]原 = 1000 0001
第一位是符號位. 因為第一位是符號位, 所以8位二進制數的取值范圍就是:
[01111111,11111111]
轉換為真值后即:
[127,-127 ]
原碼是人腦最容易理解和計算的表示方式。原碼也可以理解為最原始的機器碼。
反碼
反碼的表示方法是:
正數的反碼是其本身,
負數的反碼是在其原碼的基礎上, 符號位不變,其余各個位取反。
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
可見如果一個反碼表示的是負數, 人腦無法直觀的看出來它的數值. 通常要將其轉換成原碼再計算。
補碼
補碼的表示方法是:
正數的補碼就是其本身,
負數的補碼是在其原碼的基礎上, 符號位不變, 其余各位取反, 最后+1. (即在反碼的基礎上+1)。
[+1] = [00000001]原 = [00000001]反 = [00000001]補
[-1] = [10000001]原 = [11111110]反 = [11111111]補
對于負數, 補碼表示方式也是人腦無法直觀看出其數值的. 通常也需要轉換成原碼在計算其數值。
互相轉換、注意事項
注意:我們在最初的基本概念中提到了二進制和十進制的轉換方式。但是需要知道的是,一個數在計算機中的二進制表示方式叫做機器數。
而機器數是有符號的,我們將對應的最高位存放符號,0位正數,1位負數。所以機器數并不等于二進制。
由此我們才引出了真值的概念,例如:符號數 10000011,在十進制中對應的值為131,但是在機器數中,由于1表示負數,所以其真正數值是-3,而并不是131。
符號數:10000011,我們需要先消除其符號位的影響,將其調整為正數:00000011,此時將正數轉換為10進制為3,然后再加上最初的符號位表示負數,所以為-3。
需知道的是,二進制僅是以2為基數的計數方式而已,在二進制中是無法區分正數和負數的。而如果想區分正數和負數那么必須在二進制的最高一位中用0和1來表示符號以此來表示正負。那么此時最高位的0和1已經不是二進制的一種計數方式了,而只是一種符號的標識,該符號的標識則是萬萬不可以直接參與二進制的計算的。
當我們用最高位中的0和1來表示正負時,此時該二進制的數已經不再是符合二進制規則的數了,而是機器數。
二進制僅僅是以2為基數的計算方式,此時最高位的值已經不再是通過2位基數的計算方式而計算出來的,而只是一個表示正負的標識了,所以此時該數值則已經不再是符合二進制規則的數了,而是機器數。
所以,也只有機器數才可以表示正負。而機器數所對應得到的結果則是真數,而并不是10進制數。
如果此時拋出來一個問題:10000011 轉換為對應的10進制,那么對應的結果則是131,但如果是轉換為真數,則是-3。同樣的,如果是將00000011 轉換為對應的10進制,則是3,而如果轉換為真數,則也是3。
所以當我們看到一個以8位數所表示的二進制數時,則一定要確認該二進制數是表示機器數,還是二進制數?是轉換為10進制數,還是真數。其中最大的區別則是,最高的符號位到底是參與二進制的運算,還是僅僅表示符號位。
機器數轉真數:
10000011 >消除最高位1的影響先轉為正數>00000011>再將該正數以二進制的方式轉為十進制為> 3 >此時再將最初的符號添加回來>3調整為-3。
二進制數轉10進制數:
10000011 >無需消除最高位1的影響直接轉為正數>10000011>再將該正數以二進制的方式轉為十進制為 > 131>無需添加符號位>131仍然為131。
所以可知,真數和10進制數最大的區別則是是否忽略最高位,在確認完是否忽略最高位,得到最初的正數后,該正數的計算方式,則和二進制轉十進制的方式完全相同。其實就是二進制轉十進制。哈哈。
那么在注意了二進制數和機器數以及十進制數和真數的區別之后。我們則需要注意的另外一個問題則是:
機器數是包含原碼、反碼、補碼。其中三者之間是可以互相轉換的。原碼轉反碼轉補碼,這塊上面已經說明過了,而補碼則也可以通過想反的方式重新轉換為原碼。
而此處需要知曉的則是,反碼和補碼當然是不可以直接轉為真數的,而必須要通過原碼才可以進行轉換。
這個其實也沒什么問題,畢竟原碼經過層層轉換后得到補碼,而補碼又可以直接轉換為真數,當然不可能了。
接下來則是,為什么原碼需要轉換為補碼,為什么原碼不是計算機的計算方式,而是補碼?
本文原創地址為 https://www.cnblogs.com/zh94/p/16195373.html
原創聲明:作者:陳咬金、 博客地址:https://www.cnblogs.com/zh94/
為什么補碼才是計算機的真正計算方式
現在我們知道了計算機可以有三種編碼方式表示一個數. 對于正數因為三種編碼方式的結果都相同:
[+1] = [00000001]原 = [00000001]反 = [00000001]補
所以不需要過多解釋. 但是對于負數:
[-1] = [10000001]原 = [11111110]反 = [11111111]補
可見原碼, 反碼和補碼是完全不同的. 既然原碼才是被人腦直接識別并用于計算表示方式, 為何還會有反碼和補碼呢?
首先, 因為人腦可以知道第一位是符號位, 在計算的時候我們會根據符號位, 選擇對真值區域的加減。
但是對于計算機, 加減乘數已經是最基礎的運算, 要設計的盡量簡單. 計算機辨別"符號位"顯然會讓計算機的基礎電路設計變得十分復雜! 于是人們想出了將符號位也參與運算的方法. 我們知道, 根據運算法則減去一個正數等于加上一個負數, 即: 1-1 = 1 + (-1) = 0 , 所以機器可以只有加法而沒有減法, 這樣計算機運算的設計就更簡單了。
于是人們開始探索 將符號位參與運算, 并且只保留加法的方法. 首先來看原碼:
計算十進制的表達式: 1-1=0
1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2
如果用原碼表示, 讓符號位也參與計算, 顯然對于減法來說, 結果是不正確的.這也就是為何計算機內部不使用原碼表示一個數。
為了解決原碼做減法的問題, 出現了反碼:
計算十進制的表達式: 1-1=0
1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0
發現用反碼計算減法, 結果的真值部分是正確的. 而唯一的問題其實就出現在"0"這個特殊的數值上. 雖然人們理解上+0和-0是一樣的, 但是0帶符號是沒有任何意義的. 而且會有[0000 0000]原和[1000 0000]原兩個編碼表示0。
于是補碼的出現, 解決了0的符號以及兩個編碼的問題:
1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]補 + [1111 1111]補 = [0000 0000]補=[0000 0000]原
這里說明一下,二進制想加:0000 0001+1111 1111 = 1 0000 0000,但由于是8位數,所以最終的值為 0000 0000。
這樣0用[0000 0000]表示, 而以前出現問題的-0則不存在了.而且可以用[1000 0000]表示-128:
(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]補 + [1000 0001]補 = [1000 0000]補
由于我們使用原碼來表示正時,最大值為:01111111,最小值為:11111111,所以直接轉換為對應的10進制后的結果為,127,-127。
而此處使用補碼后,由于補碼的規則是,首位不變,其它反轉,并+1。所以(-1)+(-127) 剛好為-128。
使用補碼, 不僅僅修復了0的符號以及存在兩個編碼的問題, 而且還能夠多表示一個最低數. 這就是為什么8位二進制, 使用原碼或反碼表示的范圍為[-127, +127], 而使用補碼表示的范圍為[-128, 127]。
因為機器使用補碼, 所以對于編程中常用到的32位int類型, 可以表示范圍是: [-2的31次方, 2的31次方 - 1] 因為第一位表示的是符號位.而使用補碼表示時又可以多保存一個最小值。
Amazing,我們在上面最初使用原碼進行加法運算時,由于我們人腦還需要先判斷一下最高位的符號后,才能進行二進制運算,然后再添加上對應的符號位。而采用補碼后,直接將對應的符號位也參與運算,將補碼的數值直接相加,得到的竟然剛好也就是二進制轉換后的結果。這樣一來,計算機的基礎電路設計就可以更加簡單,而無需關注符號位的問題,僅需要按照二進制的加法法則執行即可。簡直完美。所以這也是補碼作為計算機的真正計算方式的原因之一!
但,補碼后所得到的值想加剛好就是直接二進制的值相加后的結果,真的是就剛好這么巧嗎?其實不然,背后還蘊含這很有意思的數學原理,詳情可參考:
深入理解原碼、補碼 & 數的機器碼表示 & 機器碼原理 & 原碼、補碼原理
位運算
文章最頂部基本概念處列到了“10進制2進制互轉”,以及“2進制加減法”對應的相關鏈接。
此處再推薦幾個在線計算的網址,便于將自己的計算結果進行二次驗證:
在線原碼、補碼、10進制互轉 & 在線進制轉換 & 在線二進制加減法
接下來則開始涉及到位運算了。
概念
什么是位運算?我們先來看下百度百科的概念:
程序中的所有數在計算機內存中都是以二進制的形式儲存的。位運算就是直接對整數在內存中的二進制位進行操作。
百度百科中所給的解釋是具備歧義性的,按照百度百科的解釋,直接對整數在內存中的二進制位進行操作就是位運算的話,那么使用二進制數進行算術運算法(+,-,*,/ )豈不是也屬于位運算?
我們再來看下維基百科所給的概念解釋:
位操作是程序設計中對位模式或二進制數的一元和二元操作。在許多古老的微處理器上,位運算比加減運算略快,通常位運算比乘除法運算要快很多。在現代架構中,情況并非如此:位運算的運算速度通常與加法運算相同(仍然快于乘法運算)。
維基百科中針對位運算的概念相對合理,通過維基百科中的概念我們可以很明顯的區分到,位運算是和加減乘除這些算數運算符是不同的。不同的CPU針對位運算的操作是較快于(乘/除)法運算的。
所以這也才是我們需要了解位運算的真正原因,那就是CPU處理器針對位運算符的計算是快于算術運算符的!在特定的編碼場景下使用位運算的執行速率則是遠遠大于算術運算的!
網絡上針對位運算較多的內容解釋是:位運算是直接對整數在內存中的二進制位進行操作,所以位運算更加節省內存、提高運算效率等等的。其實這是很不嚴謹的說法,很容易誤導大家對位運算的理解,因為所有的整數最終在計算機中都是二進制數,那么所有對整數的運算豈不是都是位運算?當然不是啦。且,位運算真正快的原因也并不是因為節省內存,而主要是因為CPU對位運算的支持!和內存并沒有較大關聯。
為何位運算CPU執行速率更快
程序中的基本運算包含:
- 算術運算:加、減、乘、除、取余
- 按位運算:按位或“|”、按位與“&”、按位取反“~”、按位異或“^”
- 移位運算:左移x<<k;右移x>>k
其中按位運算和移位運算均屬于位運算的范疇。
位運算的具體執行邏輯,我們下面會詳細說明。這里先以位運算中的 與 運算符 “&” 來簡單說明下位運算的主要執行邏輯:
& 與運算符的運算規則是:兩個位都為1時,則結果為1。如:3&5 即 0000 0011& 0000 0101 = 0000 0001,因此 3&5 的值得1。
根據與運算符的規則可知,位運算的整體執行邏輯實際是較為簡單的,更多的是進行位數的比較,從而得到一個結果,這種較為簡單的運算邏輯,則對于CPU處理器來說,在電路的設計中則也會更加簡單許多,以下為與運算符所涉及到的CPU電路圖:
而對于一個除法來說呢,在CPU中所對應的電路圖設計則是這樣的:
可以看到,整個CPU電路圖的設計復雜了不止一個層級,所以這也就是為何位運算比我們人常用的算術運算更快的直接原因了。因為對于整個CPU的執行邏輯來說從設計層面就復雜了很多。
當然,提到CPU的電路圖設計,就不得不提到對應的CPU中晶體管的特性了,而晶體管中所涉及到的開關(01)的特性也就構成了邏輯電路,從而構成了與門、或門、非門、異或門等電路特性。
這塊內容,可以參考如下鏈接:
位運算中隱藏的CPU秘密
程序中的位運算于基本電路關系
程序中位運算于基本電路-知乎
四位計算機的原理及實現
位運算的理解
程序中的取余是如何實現的
二進制乘除法的實現
CPU中的電路設計和數學的算法實現有著很精妙的聯系,計算機前輩的力量是無窮的。那到了這里,我們也就知道了程序中基本運算在執行速率上的真正差別實際上是在CPU這一層級的,了解了這些之后,我們也就可以接著開始說明位運算符的真正執行邏輯了。
(位運算僅需進行01的比較,和移位等簡單的邏輯操作,基本上和直接執行二進制的相加規則一樣,在電路設計和邏輯上均更加簡單,而乘除求余則在電路的設計中較為復雜)
本文原創地址為 https://www.cnblogs.com/zh94/p/16195373.html
原創聲明:作者:陳咬金、 博客地址:https://www.cnblogs.com/zh94/
位運算符
首先需知道的是,計算機中執行位運算,肯定是采用的補碼的方式進行的位計算哦,所以對于真值為負數的情況下,必須先轉為補碼才能進行計算。
符號 |
描述 |
運算規則 |
& |
與 |
兩個位都為1時,結果才為1 |
| |
或 |
兩個位都為0時,結果才為0 |
^ |
異或 |
兩個位相同為0,相異為1 |
~ |
取反 |
0變1,1變0 |
<< |
左移 |
各二進位全部左移若干位,高位丟棄,低位補0 |
>> |
右移 |
各二進位全部右移若干位,對無符號數,高位補0。各編譯器處理方法不一樣,有的補符號位(算術右移),有的補0(邏輯右移) |
& 與運算符
運算規則:兩位同時為1,結果才為1,否則結果為0。
0&0=0 0&1=0 1&0=0 1&1=1
例如:2 & -2
注意:負數當然是按照補碼的方式來進行位計算哦。
& 與運算符的用途:
根據與運算符的計算特性,我們常用的使用方式有:
1、判斷奇偶數
我們知道,按照二進制和十進制(除二取余)的換算方式,如果是偶數的情況下,換算為二進制后末位必然是0,如果是奇數則末位為1。比如:2 >10 ,3 > 11,100 >1100100,121 > 1111001。
所以,我們按照與運算符的運算規則,使用 if(a & 1)1表示為奇數,if(a & 1)0,則表示為偶數。
如:
121 & 1 = 1111001 & 0000001 = 0000001
2 & 1 =10 & 01 =00
使用與運算符的方式,則完全可以替代掉:if (a % 2 == 0) 來判斷奇偶數的方式,且位運算符由于CPU的支持,執行效率也更高。
關于二進制轉十進制的方式,參考基本概念中URL即可。
2、取一個數的指定位
比如取數 X=1010 1110 高4位,只需要另外找一個數,令 Y的高4位為1,其余位為0,即Y=1111 0000,然后將X和Y進行與運算,(X & Y = 1010 1110 & 1111 0000 = 1010 0000)即可得到X 的指定高4位。
如果想獲取X的低4位的數,則將Y的低4位為1,其余位數為0即可,(X & Y=1010 1110 & 0000 1111=0000 1110)便可得到X的指定低4位。
| 或 運算符
運算規則:兩個位都為0時,則結果為0。否則則為1。
0|0=0 0|1=1 1|0=1 1|1=1
例如:2 | -2 =-2
| 或運算符的用途
首先與和或是兩個相反的概念,所以上述所提到的與的用途,在這里只要略作改造就也適合于或運算符。但是
目的是一樣的,所以對應相同用途的場景,這里不再贅述。
1、常用來對一個數據的某些位設置為1
比如將數 X=1010 1110 的低4位設置為1,只需要另找一個數Y,令Y的低4位為1,其余位為0,即Y=0000 1111,然后將X與Y進行按位或運算(X|Y=1010 1111)即可得到。
同樣的,使用 & 運算符,則可以方便的將某些位設置為 0,如上述的X & Y,將X的低4位設置為0,則
X & Y = 1010 1110 & 1111 0000 = 1010 0000。
以上則說明 & 和 | 靈活運用,其實是可以達到相同效果的。但實際使用中則并不然,首先對于上述低4位設置為1的場景,我們只需要找一個Y的數,令Y的低4位為1,其余位為0,這樣一個數是很好找的,是一個固定的數,比如:15。轉換為二進制后為1111。
但如果使用 & 運算符來面對這個場景,則需要找一個Y,Y的第四位為0,其余位置為1,這樣一個數則很難找,并且隨著位數的不同,值也是不斷變換的,比如:1111 0000=240,但如果是12位數,1111 1111 0000=4080。所以如果使用 & 運算符來在該場景下則是沒有 | 運算符更加方便的。
盡管 & 和 | 的規則相反,可靈活變更,但針對特定場景下,還是使用特定的運算符效果更佳O。
^ 異或運算符
運算規則:兩個位相同為0,相異為1。
0^0=0 0^1=1 1^0=1 1^1=0
例如:2 ^ -2
^ 異或運算符用途
1、交換兩個數
a=a^b; //a=a^b
b=a^b; //b=(a^b)^b=a^0=a
a=a^b; //a=(a^b)^(a^b^b)=0^b=0
交換兩個數的原理,即上面注釋所寫內容。
不使用位運算的方式交換兩個數,則需要定義一個中間變量C,來承接其中的一個數的交換,對于JAVA來說,定義一個新的Int 變量C,則表示內存中需開辟一個4字節的空間。
所以根據服務特性來選擇合適的方式即可,對內存使用率有強要求則使用位運算,沒要求則都可以。
static void swap(int a, int b) { int c = a; a = b; b = c;}
static void swapBit(int a, int b) { a = a ^ b; b = a ^ b; a = a ^ b;}
~ 取反運算符
運算規則:0變1,1變0。
<< 左移運算符
運算規則:將一個運算對象的各二進制位全部左移若干位(左邊的二進制位丟棄,右邊補0)。
設 a=15,即二進制數00001111,左移2位得00111100,即十進制數60。
左移一位相當于該數乘以2,左移2位相當于該數乘以2^2=4。上面舉的例子15<< 2=60,即乘了4。
(結論:左移n位等于乘以2的n次方)
設 a=-46,補碼后為,1010 1110,a = a<< 2 將a的二進制位左移2位、右補0,即得a=1011 1000,轉換為真值后為-56。
設 a=110,補碼后為:0110 1110,a = a<<2 將a 的二進制位左移2位,右補0,即得 a=1011 1000,轉換為真值后為184。
以此可知,左移n位等于乘以2的n次方,該結論僅適用于該數左移時被溢出舍棄的高位中不包含1的情況,如果溢出的高位中包含1,則不符合上述結論。
>> 右移運算符
運算規則:將一個數的各二進制位全部右移若干位,正數左補0,負數左補1,右邊丟棄。
例如:a=a>>2 將a的二進制位右移2位,左補0 或者 左補1需要看被移數是正還是負。
設 a=16,補碼后為00010000,a = a<<2 將a的二進制位右移2位,左邊補0,即得a=00000100,轉換為真值后為4。
設a=-16,補碼后為11110000,a = a<<2 將a的二進制位右移2位,左邊補1,得到a=11111100,轉換真值后為-4。
結論:右移運算符,操作數每右移一位,相當于該數除以2。
本文原創地址為 https://www.cnblogs.com/zh94/p/16195373.html
原創聲明:作者:陳咬金、 博客地址:https://www.cnblogs.com/zh94/
Java位運算
位運算本身就是處理器、計算機自身所提供的能力,所以針對位運算的使用,實際上是不限于任何編程語言的,此處之所以以JAVA為例,主要是因為本人常用的開發語言是JAVA,哈哈。
針對JAVA中位運算的使用,實際上在JDK中有這很豐富的案例,比如:
1、JDK中線程池ThreadPoolExecutor的實現當中使用Integer類型(4字節,32位)其中高3位保存線程池狀態,而低29位保存線程池內有效線程數量。
2、比如JDK的HashMap中使用位運算的方式將初始化容量的數值,快速的轉換為2的n次冪。以及計算key的hash時,根據該key的hashCode結果,再將該hashCode的高16位和低16位通過位運算的方式進行混合,以此降低hash碰撞的概率等等。
3、比如我們直接打開常用的Integer類的源碼,也會發現里面有大量的位運算的使用。
此處僅是為了通過上述舉例的方式來以此說明位運算在Java生態中的使用程度,實際上是非常豐富的,并且由于位運算獨特的計算特性,在某些相對特殊的代碼場景下,使用位運算會意想不到的將問題給簡單化。
如果想了解更多在JAVA中的使用場景和案例,建議大家直接翻看各種源碼即可。
以上是一些舉例,以下再做一些小的補充說明:
在Java當中的位運算,是只針對Int類型和Long類型有效(java中,一個int的長度始終是32位,也就是4個字節,它操作的都是該整數的二進制數,Long則是64位,表示8字節。),而對于byte,char,short,當為這三個類型時,JVM會先把他們轉換為Int類型后再進行操作。
使用 toBinaryString() 可以將對應的十進制轉為對應的補碼。
System.out.println(Integer.toBinaryString(10));//1010
System.out.println(Integer.toBinaryString(-10));//11111111111111111111111111111101
System.out.println(Long.toBinaryString(10));//1010
System.out.println(Long.toBinaryString(-10));//1111111111111111111111111111111111111111111111111111111111110110
如上代碼可知,Integer和Long轉換為補碼時,Integer為32位,Long是64位。實際上上述的基本類型32位還是64位,均是直接定義在源碼當中的,感興趣直接看對應的Integer和Long的源碼即可。
其它參考鏈接
以下參考鏈接,僅供參考,部分鏈接中的內容,可能會具備一些歧義,請讀者自行分辨。
祝福各位讀者所有看到的知識,都可以最終成為自己的知識!撒花!??ヽ(°▽°)ノ?!
位運算教程
位運算介紹
java位運算
位運算技巧
位運算常用方式