在分析之前必須先明確如下幾點(diǎn):
1.Java是用補(bǔ)碼來(lái)存儲(chǔ)負(fù)數(shù)的靠柑,也就是說(shuō)我們對(duì)一個(gè)數(shù)進(jìn)行取反輸出,輸出的其實(shí)是一個(gè)在內(nèi)存中以補(bǔ)碼形式所存在的數(shù)吓懈;
2.原碼歼冰,反碼,補(bǔ)碼的轉(zhuǎn)換規(guī)則:{
(1)正數(shù)的原碼耻警,反碼隔嫡,補(bǔ)碼完全一樣即符號(hào)位固定為0數(shù)值位相同;
(2)負(fù)數(shù)的符號(hào)位固定為1甘穿,由原碼轉(zhuǎn)變?yōu)檠a(bǔ)碼時(shí)的規(guī)則如下:? {
? ? (1)原碼符號(hào)位為1固定不變腮恩,整數(shù)的每一位二進(jìn)制數(shù)位取反得到反碼;
? ? (2)反碼符號(hào)位為1不變温兼,在反碼數(shù)值位最低位加1秸滴,得到補(bǔ)碼。
? }
}
注:對(duì)一個(gè)數(shù)取反募判,得到的可不是它的反碼哦荡含!
舉例:
public class Test{
? ? ? public static void main(String[] args){
? ? ? ? ? ? ? ? int a = 8;
? ? ? ? ? ? ? ? System.out.println(~a);//測(cè)試發(fā)現(xiàn)輸出-9,而不是大多數(shù)人認(rèn)為的7
? ? ? }
}
分析:
正數(shù)8的二進(jìn)制表示如下:
00000000 00000000 00000000 00001000 ? (正數(shù)8的原碼届垫,補(bǔ)碼释液,反碼都是這串二進(jìn)制數(shù))
對(duì)正數(shù)8進(jìn)行取反得:
11111111 11111111 11111111 11110111(*)
可以發(fā)現(xiàn)對(duì)正數(shù)8進(jìn)行取反后由于符號(hào)位變成了1故得到了一個(gè)負(fù)數(shù)然而java存儲(chǔ)負(fù)數(shù)時(shí)是用其補(bǔ)碼來(lái)進(jìn)行存儲(chǔ)的即問(wèn)題轉(zhuǎn)化為求由于對(duì)正數(shù)8取反所得的負(fù)數(shù)存儲(chǔ)問(wèn)題!按照負(fù)數(shù)原碼和補(bǔ)碼轉(zhuǎn)化規(guī)則:
1.(*)的符號(hào)位1不變装处,其它位取反得到反碼:
? ? ?10000000 00000000 00000000 00001000
2.反碼的符號(hào)位不變误债,反碼的數(shù)值位最低位加1,得到補(bǔ)碼:
? ? ?10000000 00000000 00000000 00001001(該串二進(jìn)制數(shù)即為輸出的-9)
以上就是為什么對(duì)正數(shù)8取反操作后輸出的值為-9的原因妄迁。