你不會還不知道按位取反運算的原理吧

引入

首先來看一個程序,分別打印4-4的取反運算結果,代碼:java

public static void main(String[] args) {
    System.out.println(~4);
    System.out.println(~(-4));
}

不妨思考一下結果,若是結果是-4和4的話,那請繼續看下去吧.顯然結果不是你想的那樣,一塊兒看下:
web

187MFUkJ
187MFUkJ

沒錯,結果就是-5和3(可不是相反數那麼簡單的喲),這裏先告訴一個萬能計算公式,要計算一個整數的取反運算,好比x,那麼:app

~x = -(x+1);

理解

雖然有計算公式,相信你仍是跟我同樣,想弄清楚爲何是這樣的結果.
首先來看,~這個計算符號的定義是什麼?
按照我平時的理解,當我使用~按位取反運算的時候,計算機會將操做數所對應的二進制表達式的每個位進行取反計算,取反後所獲得的值就是~按位取反的運算結果(這點沒問題),可是怎麼去理解呢,咱們來具體分析下.學習

在這以前,先說一下計算機中的數據表示:
咱們平時學習的二進制表示有三種形式:原碼,反碼和補碼;
然而計算機只認識補碼,原碼和反碼只是人們方便計算人爲定義的,因此計算機中的全部計算二進制的輸入輸出都是補碼的形式,理解到這點,就能夠繼續往下看了.spa

仍是上面的程序,咱們對4進行取反運算,過程以下:code

  1. 4的二進制表示(補碼): 0 100
  2. 計算機對它進行按位取反: 1 011
  3. 這時計算機將計算結果反饋給咱們,獲得的答案是: -5

可能你仍是納悶,爲何1011就獲得-5了呢,不該該是-3嗎?
回到剛剛說的,計算機中全部二進制輸出都是補碼的形式,所以1011是某一個數的補碼錶示形式,咱們須要把他轉成咱們能理解的二進制:orm

  1. 首先看補碼1 011,最高位爲1,表示是一個負數,所以符號位不變,而後減1,獲得反碼(補碼 = 反碼 + 1,反之): 1 010;
  2. 將反碼1 010符號位除開,按位取反獲得原碼: 1 101,這不就是-5了嘛.

同理,咱們再看-4取反:blog

  1. 64的二進制表示(補碼): 1 100
  2. 計算機對它進行按位取反: 0 011
  3. 這時計算機將計算結果反饋給咱們,獲得的答案是: 3

那爲何又是3呢?
很簡單,補碼0 011最高位爲0,說明是正數,而正數的原碼和補碼是同樣的,因此直接等於3.ci

public static void main(String[] args) {
    System.out.println(~4);
    //補碼: 0 100
    //取反: 1 011
    //反碼: 1 010
    //原碼: 1 101 = -5
    System.out.println(~(-4));
    //1 100
    //1 011
    //補碼: 1 100
    //取反: 0 011
    //原碼: 0 011 = 3}
> 歡迎關注 [碼之淚殤](http://www.gongsir.club)
相關文章
相關標籤/搜索