91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

基礎位運算基本原理和應用

發布時間:2020-08-11 12:12:27 來源:網絡 閱讀:418 作者:程序猿洞曉 欄目:軟件技術

微信公眾號

基礎位運算基本原理和應用
位運算是編程語言的基礎,在看源碼的時候會看到很多位運算代碼,但是在項目代碼中很少會看到位運算。因為應用代碼中,有很多判斷和計算都可以直接用數值的判斷和計算完成,沒有必要去用位運算,以至于這些基礎的東西慢慢用的越來越少,慢慢也就忘了。導致的一個結果就是看源代碼很費力,因為大量的位運算邏輯,看不懂。
作為程序員感覺數據位運算是非常必要,有點如下:

  • 看源碼時能夠更好的理解
  • 位運算更接近計算機的習慣,執行的效率會更高
  • 裝逼利器,在項目中使用位運算,體現逼格

N種基本的位運算

位運算 -- 與運算符(&)

運算規則:

操作數1 0 0 1 1
操作數2 0 1 0 1
與運算 0 0 0 1

規則總結:只有兩個操作數都是1的時候運算結果才為1,其他都是0。換句話說就是只要包含0就是0。

運算如下:

基礎位運算基本原理和應用

位運算 -- 或運算符(|)

運算規則:

操作數1 0 0 1 1
操作數2 0 1 0 1
或運算 0 1 1 1

規則總結:只有兩個操作數都是0的時候運算結果才為0,其他都是1。換句話說就是只要包含1就是1。

運算如下:

基礎位運算基本原理和應用

位運算 -- 非運算符(~)

運算規則:

操作數 1 0
或運算 0 1

規則總結:取反操作,1變0,0變1。

位運算 -- 異或運算符(^)

運算規則:

操作數1 0 0 1 1
操作數2 0 1 0 1
或運算 0 1 1 0

規則總結:操作數相同,運算結果就是0,反之操作數不同就為1。
基礎位運算基本原理和應用

位運算 -- 有符號位移運算符(>>,<<)

在二進制里面總共有32位,0-31,第31位是表示當前數值的正負,當時0的時候表示這個數值是正數,當是1表示這個數值是負數。

正數左移(<<)

以2<<2為例。
2:00000000 00000000 00000000 00000010
向左移動兩位,右側會空出來兩個位置,兩個位置用0補位得到的結果如下:
8:00000000 00000000 00000000 00001000
轉換成十進制對應的數值為8。因此可以得到2<<2的結果是8。

負數左移(<<)

以-2<<2為例。
-2:11111111 11111111 11111111 11111110
向左移動兩位,右側空出的兩個位置用0補位,到這里還沒有結束,要是想計算出它的值,還要做補位,那就是將當前移位得到的結果(11111111 11111111 11111111 11111000)減一后再取反碼,得的結果就是補碼的結果。
減一操作:
11111111 11111111 11111111 11110111
取反碼的結果:
00000000 00000000 00000000 00001000
這個對應的值是8,因為是負值,那么得到的結果就是-8,因此-2<<2的結果是-8。

左移總結

這里可以看出來,在左移的時候,不論這個目標值(2或-2)是正數還是負數,結果都符合一個規律,即表達式:$m*2^n$。m表示目標值,n表示的是移位的位數。
-2<<2 = -8,2<<2 = 8,同理可以得到2<<4 = 2x2^4 = 32,-2<<4 = -2x2^4 = -32。

正數右移(>>)

以10>>2為例。
10:00000000 00000000 00000000 00001010
右移兩位,右側的10就會被舍棄,左側會空出兩個空位,空位用符號位補齊,前面說過正數的符號位是0,也就是用0補齊,得到的結果如下:
2:00000000 00000000 00000000 00000010
得到的十進制結果是2,結論就是10>>2=2。

負數右移(>>)

以-10>>2為例。
-10:11111111 11111111 11111111 11110110
同樣是右移,溢出的部分舍棄,空位的部分用符號位補齊,得到的結果如下:
11111111 11111111 11111111 11111101
減一操作后結果:
11111111 11111111 11111111 11111100
取反碼后的結果:
00000000 00000000 00000000 00000011
對應的十進制結果是3,因為是負數,那么結果就是-3。結論是-10>>2。

有符號位移總結

整體的總結來看,正數的左移和右移沒有什么問題,但是負數存在一個補碼的問題,比較麻煩。補碼記住一個口訣就可以,移位、補碼、減一、取反碼,得到正數結果加個負號。這樣就可以得到正確結果。

位運算 -- 無符號位移運算符(>>>)

Java中沒有無符號左移的說法,這里只說右移。同樣也是分正數和負數來講。

正數右移(>>>)

以10>>>2為例。
10:00000000 00000000 00000000 00001010
右移后,左側空出的位置用0補齊,但是這里需要注意的是這個0并不是指符號位,只是一個普通的補位。得到的結果如下:
2:00000000 00000000 00000000 00000010
得到的十進制結果是2,結論就是10>>2=2。這個和有符號位移是得到相同的結果。

負數右移(>>>)

以-10>>>2為例。
-10:11111111 11111111 11111111 11110110
右移后,左側空位用0補,注意不是用1補,后面說原因。
00111111 11111111 11111111 11111101
這個結果就很大了,結果是1073741821,負數變成了這么大的負數,不要懷疑自己的眼神,這個結果是正確的。

總結

所謂的無符號右移,就是將原有的二進制值直接右移得到結果,不論是負數還是正數,沒有補碼的操作,補位都統一使用0,而不是對應的符號位1或0。
到這里N種基本的位運算已經說明結束,接下來看幾個例子,和在代碼中常用的一些技巧。

常用位運算使用
  • 判斷一個數是奇數還是偶數。
    // true表示為奇數,false表示為偶數
    public boolean checkNum(int num){
    return (num&1) == 1;
    }

    1的二進制是00000000 00000000 00000000 00000001,&運算的規則是只有都是1,結果才是1,很明顯,不管是什么數,和1進行&運算,前31位都是0,只有最后一位可能得出不同的結果。偶數最后一位肯定是0,奇數肯定是1,那么結果就顯而易見了。

  • 不用中間變量,交換兩個數值(面試常見)
    // 傳入的a=3,b=5
    public void swap(int a,int b){
    a ^= b;// a = a^b;
    b ^= a;// b = b^a;
    a ^= b;// a = a^b;
    System.out.println("a="+a);
    System.out.println("b="+b);
    }
    /*
    輸出結果:
    a=5
    b=3
    */

    這個靈活的用到了異或來實現。下面做個簡單的說明。
    a = 3:00000011
    b = 5:00000101
    a異或b得到的結果是:00000110,這個結果賦值給a;
    b異或a得到的結果是:00000011,這個結果賦值給b;
    a異或b得到的結果是:00000101,這個結果賦值給a;
    所以最終得到的結果是:
    a = 5:00000101
    b = 3:00000011

  • 取絕對值
    public int getAbs(int n){
    return (n ^ (n >> 31)) - (n >> 31);
    }

    具體不說,可以自己嘗試著寫一下。(因為涉及到正數、負數的舉例,然后負數又有補碼操作,要寫的內容太多,本博主就傲嬌一下,不寫啦!)
    其實這里的例子很多,就不都去說了,有興趣的可以度娘一下相關的博客,有很多文章。

實際項目經驗操作

涉及到公司的東西,這里不會寫的很具體,給思路。

現在有一個訂單,訂單可以進行很多操作,如:創建、修改、退單、接單、終止、派單、提交完成等操作。同時訂單也有很多狀態,如:待接單、進行中、已終止、已完成等狀態。現在的場景就是不同的狀態對應的操作是不一樣的,前端需要根據不同的狀態顯示不同的操作控件。

思路一:

最簡單也是最麻煩的,用N個flag字段表示可進行的操作,返回數據的時候對每個flag字段賦值true、false,表示是否能夠進行此操作。但是這樣存在一個巨大的問題,當后期有一個操作去掉了或者添加了幾種新的操作,這個時候就涉及到字段的刪除和新增,改動較大,可維護性差,不夠靈活。

思路二:(推薦)

使用此二進制的方式表示。實現如下:

第一位:0,1表示是否可以修改

第二位:0,1表示是否可以接單

第三位:0,1表示是否可以終止

返回給前端只要一個字段tags,如對應的值是:010,那就表示不可以修改、可以接單、不可以終止。

如果現在終止操作不要了,那么這個二進制位始終給0就可以。如果新增了一個提交操作,那就讓第四位表示是否可以提交。這樣不需要添加字段,只要在原字段加一位就OK。

另外還有其他很多應用場景。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

东宁县| 夏津县| 大宁县| 璧山县| 扶绥县| 平顶山市| 台山市| 石首市| 太仓市| 石渠县| 嵊泗县| 巩留县| 慈利县| 佛学| 松滋市| 左贡县| 天镇县| 新野县| 石景山区| 桐柏县| 江门市| 天峨县| 梁平县| 东莞市| 兴宁市| 莱阳市| 浏阳市| 四会市| 都昌县| 木兰县| 新绛县| 东乡族自治县| 岑溪市| 聊城市| 广平县| 伊金霍洛旗| 任丘市| 白玉县| 上栗县| 同德县| 涪陵区|