本文對C++中的short類型的取值范圍-2^15~2^15-1在內存中的二進制儲存做了一點理解,其他的int,long等整型與此類似。
預備:
11? ? ? 2^2-1
111? ? 2^3-1
1111? 2^4-1
10? ? ?2^1
100? ?2^2
1000 2^3
問題描述:
我發(fā)現這個-2^15是1000 0000 0000 0000,但是2^15-1是0111 1111 1111 1111。
然后我就不理解這個編號到底是怎么連續(xù)地排過去的,1000 0000 0000 0000下一個數字該是1000 0000 0000 0001,然后原來越小,而0111 1111 1111 1111是short能表示的最大正數很好理解,它下一個數字該是0111 1111 1111 1110,它也會越來越小,感覺前后這兩個數字接不到一起(+_+)?
實際上仔細看這個1000 0000 0000 0000,它那個1是符號,它其實是個-0,它并不是-2^15,-2^15是計算機規(guī)定的,就是為了去掉這個-0,因為已經有+0了(0000 0000 0000 0000)。
從全0到全1,所有的short類型數據的邏輯如下:
0 000 0000 0000 0000? ? ? ? ? (0)
0 000 0000 0000 0001? ? ? ? ? (1)
0 000 0000 0000 0010? ? ? ? ? (2)
~
0 111 1111 1111 1101? ? ? ? ? (2^15-3)
0 111 1111 1111 1110? ? ? ? ? ? ?(2^15-2)
0 111 1111 1111 1111? ? ? ? ? ?(2^15-1,這是最大正數了,再加1符號位就變了)
1 000 0000 0000 0000? ? ? ? ? ? (-0)? (你有點多余)
1 000 0000 0000 0001? ? ? ? ? ? ? (-1)
1 000 0000 0000 0010? ? ? ? ? ? ? (-2)
1 000 0000 0000 0011? ? ? ? ? ? ? ?(-3)
~
1 111 1111 1111 1101? ? ? ? ? ?(-2^15-3)
1 111 1111 1111 1110? ? ? ? ? ?(-2^15-2)
1 111 1111 1111 1111? ? ? ? ? ? (-2^15-1)
捋下來之后發(fā)現,要是沒這個-0(1 000 0000 0000 0000)那么表示的范圍剛好是[-2^15-1, -2^15-2, -2^15-3..., -3, -2, -1, 0, 1, 2, 3, ..., 2^15-3, 2^15-2, 2^15-1],但是這個-0就很難受,那1+(-1)到底是等于+0還是-0?于是計算機底層在用補碼存儲數據的時候,規(guī)定這個-0(1 000 0000 0000 0000)就取它字面上的值,1 000 0000 0000 0000要是個無符號整型數據表示的就是2^15,但是又規(guī)定把它劃到負數那邊,于是負數就多了一個(-2^15)。也就是說,這個-2^15(1 000 0000 0000 0000)的負號,是計算機規(guī)定的,不是這個字面上的二進制數表示出來的,這個數從字面上看,他要是有符號,應該是-0,要是無符號,應該是2^15,怎么也不能-2^15,這是規(guī)定的!
另外插一句,有符號二進制數從全0開始+1,+1,+1加到全1,按它的順序對應的十進制數的順序不是咱們常規(guī)的...-3, -2, -1, 0, 1, 2, 3...這樣由大到小很順暢的排序,而是0,1,2,3,...,最大正數,-0,-1,-2,-3,...,最大負數,但是我們說short的范圍的時候說-2^15~2^15-1,感覺好像二進制數也是所有的都從小到大在排一樣,其實不是╮(╯-╰)╭,這要注意一下。
而且以上所有的二進制數都是補碼的形式,要-1倒成反碼,再取反(除了符號位)倒成原碼,才能是它真實的表示的數值,不過這個不影響我們討論short的取值范圍。
總之short只能占2個字節(jié),也就是16位,這16位總共可以表示2^16個數字,這2^16個數字按照第一位是0還是1分成正數和負數,正負數各2^15個,正數從0到2^15-1,負數從-0到-2^15-1,為了去掉這個-0,計算機規(guī)定-0(1000 0000 0000 0000)表示的是-2^15,把它算到負數那邊去,于是負數就比正數多了一個。于是取值范圍本來應該是-2^15-1~2^15-1,現在變成了-2^15~2^15-1。
如有錯誤,歡迎指正*^____^*