進制
程序中的所有數在計算機內存中都是以二進制的形式儲存的。位運算說穿了,就是直接對整數在內存中的二進制位進行操作。
首先呢,了解位運算之前,我們要先指定進制之間的轉換
眾所周知我們生活中所用的使用的數字是十進制數,而計算機所認識的是二進制
所以呢,作為一個程序員我們必須要掌握二進制與十進制之間的互轉與運算
二進制中的一些關鍵字:
1)高位
一串二進制串,左面為高位
2)低位
一串二進制串,右面為低位
3)原碼
我們所認識的二進制碼,也就是我們進制間轉換所得到的值,我們認識,但計算機不認識
4)反碼
正數不需要做反碼操作,,,負數的反碼:符號位不變,0變1,1變0 -------反碼是原碼轉為補碼的中間過程
5)補碼
計算機所認識並可計算的字節碼,正數的補碼還是其原碼本身,,負數的補碼是其反碼+1
01.正數的原碼,反碼,補碼都一致
02.java中所有的數字都是有符號的 符號位 正數0 負數1
03.負數的反碼=符號位不變+其他位取反(1變0 0變1)
04.負數的補碼=反碼+1
十進制轉二進制
可以明確的說,只要你會加法你就可以秒轉
先來一張比較牛逼的表:
1024 512 256 128 64 32 16 8 4 2 1
看不懂?沒關系,接下來我們來說
我們隨便拿來一個數:765 (為了說明我這個辦法確實nb,我們拿了一個比較大一點的數)
我們已經有表了,那么,就套表唄
首先找到765最近的一個比他小的數
在他下面寫個1,也就是512
然后依次往后相加,發現相加比765大那么下面寫0,然后舍去,只然后加下一個(注意是下面寫過1的連續相加)最后可以得出來:
| 1024 |
512 | 256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
| 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
765的二進制數就是0 1011111101 (最前的0當符號位)
因為是正數所以這既是它的原碼也是它的補碼
那如果是負數呢?-765
簡單,就是拿到其正數的二進制數,改變符號位拿到原碼:
1 1011111101 這個值是我們轉換的二進制碼
然后取反碼(0變1,1變0,)
也就是 1(符號位不變) 0100000010 然后補碼+1
1 0100000011
-765的補碼就是1 0100000011 這個值是計算機可以進行計算解析的二進制碼
二進制轉十進制
可以明確的說在這里你只要會乘法運算,和明白數組下標就會秒轉 或者拿出上面的萬能轉換表
還是老規矩,隨便寫一個0和1組成的字符串,然后正負兩種情況
符號位為正:
隨便一個0符號位的二進制串 (既是原碼也是補碼)
0 1101 ok,發大招,轉換
先忽略符號位,將后面的二進制串我們看成一個倒着的int類型數組,低位為0,依次往做+1
古老算法:
當前數*2的下標次方,然后將所有的數相加
那么這個數就是:
1*2的0次方+1*2的2次方+1*2的3次方=1+4+8= 13
然后加上符號位
那么最終值就是+13
萬能表算法:
| 1024 |
512 | 256 | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
| 1 | 1 | 0 | 1 |
那么。。。就是 8 +4 +1=13
完美!!!
符號位為負:
如果拿到的是一個原碼,,那就跟上面算法一樣,只不過符號位為負的而已
如果拿到一個補碼,也就是中間多兩部操作
上面說了,原碼轉補碼是 原碼取反+1
那么,反推,補碼轉原碼就是。。。補碼-1取反
得到原碼,再用上面其中一種算法就ok了
位運算
算術右移 >>
符號位不變,低位溢出刪除,高位補零!
舉個例子:5>>2 (解析:把五的二進制數右移兩位)
先算出5 的二進制:
0 101 右移兩位,符號位不變
0 00101 低位溢出刪除,高位補零!
最后結果:0 001
轉回十進制就是1
如果是負數就是先轉碼然后位移
算術左移 <<
符號位不變,高位溢出刪除,低位補零!
舉個例子:5<<2 (解析:把五的二進制數右移兩位)
先算出5 的二進制:
0 101 左移兩位,符號位不變
0 10100 高位溢出刪除,低位補零!
最后結果:0 10100
轉回十進制就是20
如果是負數就是先轉碼然后位移
邏輯右移 >>>
又叫無符號右移
不管符號位!低位溢出刪除,高位補零!
所以呢,,邏輯右移的其值永遠是正數,剩下的跟算術右移大同小異
無符號右移的規則只記住一點:忽略了符號位擴展,0補最高位 無符號右移運算符>>> 只是對32位和64位的值有意義
按位與 &
兩位都為1,結果為1
取 5&3
5 二進制:101
3 二進制:011
101
& 011
001
結果為1
按位或 |
兩位有一位為1,結果為1
取5|3
5 二進制:101
3 二進制:011
101
| 011
111
結果為:7
按位異或 ^
必須是一位是0,一位是1,結果才為1
取5^3
5 二進制:101
3 二進制:011
101
^ 011
110
結果是:6
按位取反 ~
取~3
3 二進制:0 011
整體取反 1 100
負數。。。補碼轉原碼,原碼轉十進制
-1取反:011 100
符號位為1,所以最后值:-4
最后發現,
有個規律:就是數值+1之后取相反的值
