java語言對應數學中邏輯運算
"∧" 表示 "與" 對應java : &
"∨" 表示 "或" 對應java : |
"┐"表示 "非" 對應java : ~
a⊕b = (¬a ∧ b) ∨ (a ∧¬b) 異或(xor) 對應java : ^
在計算機中,數值一直以補碼存儲,運算也用補碼。
ex:8bit signed int (-128~127),最高位為符号位,0000 0000 ~ 1111 1111 以補碼形式存儲 帶符号數
0000 0000 :十進制0 1+(-1)=0,其實用的是1的補碼和-1的補碼相加。正數的補碼為本身
0000 0001 :1(0+1) 即0000s 00001+?= 0000 0000 當?為1111 1111 時相加為1 0000 0000 最高位進位被舍棄
.... 由此誕生了-1在計算機中存儲的二進制 1111 1111,即-1的補碼
0111 1111 : 127 所有從 1~127 都有對應的-1~-127,一個數的補碼+該數相反數的補碼 = 0(1 0000 0000)
1000 0000 : -128 多出了 0000 0000 (0的補碼)和 1000 0000 (-128的補碼)
....
1111 1111 : -1 從-128(1000 0000)+1.... -1(11111 1111))+1 = 0 (0000 0000) +1.... 127 (0111 111)
驗證計算機隻會做加法,且帶符号位(8 bit)整型範圍(-128 ~127)
同時可以證明 負數的補碼=相反數的補碼按位取反+1
正數原碼=補碼=反碼,涉及負數才有補碼反碼之間計算
原碼:1010(-2)
補碼:1110
補碼 = (原碼)按位取反+1(原碼除符号位按位取反+1)
在位運算中計算得知補碼後怎麼轉換為直覺的原碼
原碼 = (補碼 -1)後除符号位按位取反
原碼 = 反碼(補碼除符号位取反) +1
Java中沒有無符号資料類型,取最高位作為符号位表示正負數,但運算和位操作都使用補碼計算
與運算 & 規則 :對應數的補碼對應位都為1時結果位才為1
System.out.println( 7 & 9);//result為1
分析:
7的二進制:0111(即為源碼也為補碼)
9的二進制:1001
result :0001
System.out.println(-1&-2); //輸出-2
分析:
-1原碼:1001 對應補碼:1111
-2原碼:1010 對應補碼:1110
result: 得到補碼:1110(即負數補碼,-2的補碼)
1101 補碼-1 或 1001 除符号位按位取反得反碼
1010 按位取反得原碼,即帶符号的-2 1010 反碼+1得原碼 -2
同理或運算,異或運算,取反運算相同,都為對補碼行運算
輸出結果
或運算 | 規則:有一個位為1,則結果位為1
System.out.println(7 | 9);// 15
分析:
7的二進制:0111
9的二進制:1001
result :1111
異或運算 ^ 規則:對補碼不同位不同為1
System.out.println( 7 & 9);//result為14//System.out.println((~7&9)|(7&~9));//結果相同
分析:
7的二進制:0111
9的二進制:1001
result :1110
取反運算 ~ 規則:對補碼按位取反
System.out.println( ~7);//輸出-8
分析:
7的二進制:0000 0000 0000 0000 0000 0000 0000 0111
正整數的原碼=補碼,然後對補碼求反
result: 1111 1111 1111 1111 1111 1111 1111 1000 //符号位改變(第一位),取反之後變成負數了(即負數的補碼)
1000 0000 0000 0000 0000 0000 0000 0111 //反碼(除符号位取反)
1000 0000 0000 0000 0000 0000 0000 1000 //對反碼+1(得原碼)== -8
System.out.println( ~-7);//輸出6
分析:
-7的二進制:1000 0000 0000 0000 0000 0000 0000 0111 //該為原碼,計算機中存儲,計算的為補碼,需轉換為補碼再按位求反
result: 1111 1111 1111 1111 1111 1111 1111 1001 //補碼
0000 0000 0000 0000 0000 0000 0000 0110 //對補碼求反仍然為補碼
// 但符号位為0 即正數,補碼=原碼 == 6
移位運算 << (有符号左移), >>(有符号右移) , >>>(無符号右移)
<< :左移後,低位補0
>> :右移後,正數高位補0,負數高位補1
>>> :無符号右移,高位都補0
a << n 左移n位,值為a*2^n
a >> n 右移n位,值為a/2^n