java 取反學(xué)習(xí)

問題


最近學(xué)習(xí)java 位操作,取反運(yùn)算遇到了問題。

public class bitMpt {
        public static void main(String[] args) {
            int a = 128;
            int b = 129;
            int c = 2;
            System.out.println("a and b result: "+(a&b));
            System.out.println("a or b result: "+(a|b));
            System.out.println("~ c result: "+(~c));
            System.out.println("a ^ b result: "+(a^b));
        }
}

c = 2 取反,10變01, 結(jié)果應(yīng)該為1,但運(yùn)行結(jié)果為-3。

知識(shí)點(diǎn)


java存儲(chǔ)的是有符號(hào)數(shù),在計(jì)算機(jī)中,有符號(hào)數(shù)通常是使用補(bǔ)碼存儲(chǔ)的。

原碼

原碼就是符號(hào)位加上真值的絕對(duì)值,即用第一位表示符號(hào), 其余位表示值. 比如如果是8位二進(jìn)制:

[+1]原 = 0000 0001

[-1]原 = 1000 0001
第一位是符號(hào)位. 正數(shù)符號(hào)位為0,負(fù)數(shù)為1。

反碼

正數(shù)的反碼是其本身
負(fù)數(shù)的反碼是在其原碼的基礎(chǔ)上,符號(hào)位不變,其余各個(gè)位取反.
例如:

[+1] = [00000001]原 = [00000001]反

[-1] = [10000001]原 = [11111110]反

補(bǔ)碼

正數(shù)的補(bǔ)碼就是其本身
負(fù)數(shù)的補(bǔ)碼是在反碼的基礎(chǔ)上+1。
例如:

[+1] = [00000001]原 = [00000001]反 = [00000001]補(bǔ)

[-1] = [10000001]原 = [11111110]反 = [11111111]補(bǔ)

總結(jié)


所以回到一開始的問題,int a = 2 a在計(jì)算機(jī)中是以補(bǔ)碼存儲(chǔ)的。
對(duì)于2這個(gè)正數(shù)來說,補(bǔ)碼、反碼、原碼都是相同的,又由于是數(shù)值型,在這里我先用八位bit來表示一下:

原碼:0000 0010反碼:0000 0010

補(bǔ)碼:0000 0010
取反取反過程是在補(bǔ)碼的基礎(chǔ)上進(jìn)行的,由于是按位取反,無論符號(hào)位還是數(shù)值位都要取反,所以結(jié)果如下:

取反后的補(bǔ)碼: 1111 1101

換算為值那么取反后的補(bǔ)碼的實(shí)際值是多少呢?我們需要先把他轉(zhuǎn)化為原碼,過程如下:

反碼 = 1111 1101 - 1 = 1111 1100

原碼 = 反碼符號(hào)位不變,其余取反 = 1000 0011
所以,最后的值-3

<small>[參考] https://segmentfault.com/a/1190000004877495

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容