Go 位運算符的使用

位運算在平時寫代碼時不常用到,但是在很多的官方和非官方的優秀代碼中經常會看到,被這些位運算的操作所驚豔。如果在平時的擼代碼過程中,能夠用到提升性能的位運算同時代碼也顯得很簡潔,那何樂不爲呢。

下面簡單介紹下各個運算符以及可能會使用到的場景

二元運算符

  1. & 與運算符 AND

    當兩個數二進制位同爲 1 的時候當前位置 1,否則置 0

& 15 = 4
---------------
00000100 &
00001111
00000100
=4

位運算的使用場景

func IsOdd(i int)bool{
return i%2!=0
}
 位運算判斷
func IsOdd(i int)bool{
return (& 1) == 1 //i 是否爲奇數取決於二進制的最後一位是 1 還是 0 是 1 則爲奇數 0 則爲偶數
}
func BitCheck(i int)(count int){

for i>0{
    count = count + (i&1)
    i >>= 1
}
return 
}
 如果數值中間有多個 0 需要多次判斷,優化方法是值 x 如果不爲 0 那麼和`x-1`進行與操作就會找出最低位的 1
/*
10110001 &  //初始值 
10110000    //減 1 
=10110000 &  //找出最低位的 1
10101111   //繼續減 1
=10100000   //找出最低位的 1
....       //直到找不出 1 即爲 0
*/

func BitCheck(i int)(count int){
for i>0{
        count += 1
        i &= i-1
}
return
}
  1. | 或運算符 OR

    當兩個數二進制位有一個爲 1 時當前位置 1,同爲 0 的時候當前位纔會置 0

| 15 = 15
---------------
00000100 |
00001111
=15
  1. ^ 異或運算符 XOR

    ^ 即可作爲二元運算符,也可作爲一元運算符。

    作爲二元運算符,^ 是異或運算符。

    兩個數的二進制位不同時,當前位才置 1 否則置 0

    有個很明顯的規律 任何數和本身異或 結果爲 0, 0 和任意數異或 結果爲其本身

| 15 = 11
---------------
00000100 ^
00001111
00001011
=11

例子

a ^= b // a = a^b
b ^= a // b = b^(a^b) b 和 b 自己異或爲 0 相當於 b=a
a ^= b // a = (a^b)^a a 在第一步中已經爲 a^b,現在的 b 已經等於 a a 互相抵消 完成了值的交換
func SingleNum(list []int)(target int){
target = list[0]
for _,val:=range list[1:]{
    target ^= val
}
return
}
  1. &^ 位清空運算符 AND NOT

    看一個列子

&15 = 11
---------------
00000100 &^
00001111
00000000
=0

位清空的意思是 假如有 兩個變量 var1 &^ var2 作位清空運算

  1. <<和>> 左移和右移運算符

    兩個運算符左側總是爲要進行位移操作的變量,右側爲需要移動的位數值。

    之前因爲看到  32<<0=32  就有點懵,以爲是 0 左移 32 位 不明白爲什麼結果爲 32,就是因爲把 32 當做要位移的位數了。

1<<N = 2^N
-----------
1 左移多少位等於 2 的多少次方
1024>>N = 1024/2^N
---------------
右移 N 位 相當於除以 2 的 N 次方

關於左移、右移 , 有一個 Go 在寫磁盤單位 GB MB KB 等大小定義的例子

在使用const關鍵字的時候 可使用內置變量 iota從 0 開始自動遞增

在遇到下個常量塊或者單個常量定義的時候 也就是再一次使用 const 關鍵字的時候 iota 置 0

package main
type ByteSize float64
const(
    B ByteSize = 1<<(10*iota)  // 1<<(10*0)
    KB  // 1<<(10*1)
    MB  // 1<<(10*2)
    GB  // 1<<(10*3)
    TB  // 1<<(10*4)
    PB //  1<<(10*5)
)

轉自:

juejin.cn/post/6844903955718225928

Go 開發大全

參與維護一個非常全面的 Go 開源技術資源庫。日常分享 Go, 雲原生、k8s、Docker 和微服務方面的技術文章和行業動態。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/8wubPDKO6-CLLhqjGsJ7xw