Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Analisis ringkas operasi bit (pengendali bitwise) di Golang

Analisis ringkas operasi bit (pengendali bitwise) di Golang

青灯夜游
青灯夜游ke hadapan
2023-02-24 19:42:254413semak imbas

Analisis ringkas operasi bit (pengendali bitwise) di Golang

Pada zaman dahulu apabila memori komputer mahal dan kuasa pemprosesan terhad, menggunakan operasi bit gaya penggodam untuk memproses maklumat adalah cara yang diutamakan (dan dalam beberapa kes satu-satunya cara) . Sehingga hari ini, penggunaan langsung operasi bit masih merupakan bahagian penting dalam banyak bidang pengkomputeran, seperti pengaturcaraan sistem peringkat rendah, pemprosesan grafik, kriptografi, dll.

Bahasa pengaturcaraan Go menyokong pengendali bitwise berikut:

&   bitwise AND
 |   bitwise OR
 ^   bitwise XOR
&^   AND NOT
<<   left shift
>>   right shift

Baki artikel ini memperincikan setiap pengendali dan contoh cara ia digunakan.

& Operator

Dalam Go, operator & melakukan operasi bitwise AND pada dua operan integer. Operasi AND mempunyai atribut berikut:

Given operands a, b
AND(a, b) = 1; only if a = b = 1
               else = 0

AND Operator mempunyai kesan yang baik untuk mengosongkan bit data integer secara terpilih kepada 0. Sebagai contoh, kita boleh menggunakan operator & untuk mengosongkan (menetapkan) 4 bit paling tidak ketara (LSB) terakhir kepada semua 0.

func main() {
    var x uint8 = 0xAC    // x = 10101100
    x = x & 0xF0          // x = 10100000
}

Semua operasi bit menyokong borang tugasan yang disingkatkan. Sebagai contoh, contoh sebelumnya boleh ditulis semula seperti berikut.

func main() {
    var x uint8 = 0xAC    // x = 10101100
    x &= 0xF0             // x = 10100000
}

Helah lain yang kemas ialah: anda boleh menggunakan operasi & untuk menguji sama ada nombor itu ganjil atau genap. Sebabnya ialah apabila bit terendah nombor ialah 1, ia adalah nombor ganjil. Kita boleh menggunakan nombor dan 1 untuk melakukan operasi &, dan kemudian melakukan operasi AND dengan 1. Jika hasilnya ialah 1, maka nombor asal ialah nombor ganjil

import (
    "fmt"
    "math/rand"
)
func main() {
    for x := 0; x < 100; x++ {
        num := rand.Int()
        if num&1 == 1 {
            fmt.Printf("%d is odd\n", num)
        } else {
            fmt.Printf("%d is even\n", num)
        }
    }
}

dalam Taman Permainan

| Operator

melaksanakan operasi bitwise| pada operan integernya. Ingat bahawa pengendali mempunyai sifat berikut:

Given operands a, b
OR(a, b) = 1; when a = 1 or b = 1
              else = 0
Kita boleh menggunakan operator bitwise

untuk menetapkan bit individu secara selektif untuk integer tertentu. Sebagai contoh, dalam contoh berikut kami menggunakan bitwise untuk menetapkan bit ke-3, ke-7 dan ke-8 dalam nombor sampel (dari bit rendah ke bit tinggi (MSB)) kepada 1. Contoh boleh dijalankan di

func main() {
    var a uint8 = 0
    a |= 196
    fmt.Printf("%b", a)
}

// 打印结果  11000100
            ^^   ^

Tapak Latihan. Operasi

berguna apabila menggunakan teknik penyamaran bit untuk menetapkan bit arbitrari untuk nombor integer yang diberikan. Sebagai contoh, kita boleh melanjutkan atur cara sebelumnya untuk menetapkan lebih banyak bit untuk nilai yang disimpan dalam pembolehubah

. a

Contoh boleh dijalankan di
func main() {
    var a uint8 = 0
    a |= 196
    a |= 3
    fmt.Printf("%b", a)
}

// 打印结果 11000111
Tapak Latihan

. Dalam atur cara sebelumnya, bukan sahaja perpuluhan 196 mesti ditetapkan bitwise, tetapi perpuluhan 3 dalam bit rendah juga mesti ditetapkan. Kita boleh meneruskan (lebih banyak nilai pada

) untuk menetapkan semua bit.

Konfigurasi Penggunaan Operasi Bit Sekarang, mari semak

. Kita boleh menggunakan ciri ini untuk menanyakan nilai bit tetapannya. Sebagai contoh, dalam kod di atas

akan mengembalikan 196 kerana nilai bit ini wujud dalam AND(a, 1) = a 当且仅当 a = 1. Jadi kita boleh menggunakan operasi a & 196 dan a dalam kombinasi untuk menetapkan dan membaca nilai konfigurasi bit tertentu masing-masing. .ORANDCoretan kod sumber berikut menunjukkan operasi ini. Fungsi

menukarkan kandungan rentetan. Ia memerlukan dua parameter: yang pertama,

, ialah rentetan yang hendak ditukar dan yang kedua, procstr, ialah integer yang menggunakan bitmask untuk menentukan konfigurasi penukaran berbilang. strconf

Jalankan kod pada
const (
    UPPER  = 1 // 大写字符串
    LOWER  = 2 // 小写字符串
    CAP    = 4 // 字符串单词首字母大写
    REV    = 8 // 反转字符串
)

func main() {
    fmt.Println(procstr("HELLO PEOPLE!", LOWER|REV|CAP))
}

func procstr(str string, conf byte) string {
    // 反转字符串
    rev := func(s string) string {
        runes := []rune(s)
        n := len(runes)
        for i := 0; i < n/2; i++ {
            runes[i], runes[n-1-i] = runes[n-1-i], runes[i]
        }
        return string(runes)
    }

    // 查询配置中的位操作
    if (conf & UPPER) != 0 {
        str = strings.ToUpper(str)
    }
    if (conf & LOWER) != 0 {
        str = strings.ToLower(str)
    }
    if (conf & CAP) != 0 {
        str = strings.Title(str)
    }
    if (conf & REV) != 0 {
        str = rev(str)
    }
    return str
}
Taman Permainan

Kaedah

di atas akan menukar rentetan menjadi huruf kecil, kemudian membalikkan rentetan dan akhirnya menukar aksara. Huruf pertama perkataan dalam rentetan ditulis dengan huruf besar. Fungsi ini dicapai dengan menetapkan nilai digit kedua, ketiga dan keempat dalam

kepada 14. Kod kemudian menggunakan blok pernyataan if berturut-turut untuk mendapatkan operasi bit ini dan melakukan penukaran rentetan yang sepadan. procstr("HELLO PEOPLE!", LOWER|REV|CAP)conf

^ operator

Dalam Go, operasi bitwise

diwakili oleh

. Operator 异或 mempunyai ciri-ciri berikut: ^异或

Given operands a, b
XOR(a, b) = 1; only if a != b
     else = 0
Ciri operasi ini boleh digunakan untuk menukar satu nilai bit binari kepada nilai yang lain. Sebagai contoh, diberi nilai perenambelasan, kita boleh menggunakan kod berikut untuk menukar 8 bit pertama (bermula dari MSB) nilai.

func main() {
    var a uint16 = 0xCEFF
    a ^= 0xFF00 // same a = a ^ 0xFF00
}

// a = 0xCEFF   (11001110 11111111)
// a ^=0xFF00   (00110001 11111111)

在前面的代码片段中,与 1 进行异或的位被翻转(从 0 到 1 或从 1 到  0)。异或 运算的一个实际用途,例如,可以利用 异或运算去比较两个数字的符号是否一样。当 (a ^ b) ≥ 0 (或相反符号的 (a ^ b) 087d86671d155612d4f02e9d24199fd2> 操作符<p>与其他 C 的衍生语言类似, Go 使用 <code>036118feef1720dceedad2101673ba7c> 来表示左移运算符和右移运算符,如下所示:

Given integer operands a and n,
a << n; shifts all bits in a to the left n times
a >> n; shifts all bits in a to the right n times

例如,在下面的代码片段中变量 a00000011)的值将会左移位运算符分别移动三次。每次输出结果都是为了说明左移的目的。

func main() {
    var a int8 = 3
    fmt.Printf("%08b\n", a)
    fmt.Printf("%08b\n", a<<1)
    fmt.Printf("%08b\n", a<<2)
    fmt.Printf("%08b\n", a<<3)
}

// 输出的结果:
00000011
00000110
00001100
00011000

Playground 运行代码

注意每次移动都会将低位右侧补零。相对应,使用右移位操作符进行运算时,每个位均向右方移动,空出的高位补零,如下示例 (有符号数除外,参考下面的算术移位注释)。

func main() {
 var a uint8 = 120
 fmt.Printf("%08b\n", a)
 fmt.Printf("%08b\n", a>>1)
 fmt.Printf("%08b\n", a>>2)
}

// 打印:
01111000
00111100
00011110

练习场中可以运行范例。

可以利用左移和右移运算中,每次移动都表示一个数的 2 次幂这个特性,来作为某些乘法和除法运算的小技巧。例如,如下代码中,我们可以使用右移运算将 200(存储在变量 a 中)除以 2 。

func main() {
    a := 200
    fmt.Printf("%d\n", a>>1)
}

// 打印:
100

练习场 中可以运行范例。

或是通过左移 2 位,将一个数乘以4:

func main() {
    a := 12
    fmt.Printf("%d\n", a<<2)
}
// 打印:

48

练习场 中可以运行范例。

位移运算符提供了有趣的方式处理二进制值中特定位置的值。例如,下列的代码中,|<< 用于设置变量 a 的第三个 bit 位。

func main() {
    var a int8 = 8
    fmt.Printf("%08b\n", a)
    a = a | (1<<2)
    fmt.Printf("%08b\n", a)
}
// prints:
00001000
00001100

可以在 练习场 中运行代码示例。

或者,您可以组合位移运算符和 & 测试是否设置了第n位,如下面示例所示:

func main() {
    var a int8 = 12
    if a&(1<<2) != 0 {
        fmt.Println("take action")
    }
}

// 打印:
take action

练习场中运行代码。

使用  &^ 和位移运算符,我们可以取消设置一个值的某个位。例如,下面的示例将变量 a 的第三位置为 0 :

func main() {
    var a int8 = 13 
    fmt.Printf("%04b\n", a)
    a = a &^ (1 << 2)
    fmt.Printf("%04b\n", a)
}

// 打印:
1101
1001

练习场 中运行代码。

关于算术位移运算的笔记

当要位移的值(左操作数)是有符号值时,Go 自动应用算术位移。在右移操作期间,复制(或扩展)二进制补码符号位以填充位移的空隙。

Ringkasan

Seperti pengendali moden yang lain, Go menyokong semua pengendali manipulasi bit binari. Artikel ini hanya menyediakan contoh pelbagai penggodaman yang boleh dilakukan dengan pengendali ini. Anda boleh menemui banyak artikel di web, terutamanya Bit Twiddling Hacks oleh Sean Eron Anderson.

Ikuti Vladim @vladimirvivien di Twitter.

Jika anda belajar Go, baca buku Vladimir Vivien on Go yang dipanggil Learning Go Programming .

Artikel ini pada asalnya diterbitkan di Medium oleh pengarang Vladimir Vivien sebagai Bit Hacking with Go.

Alamat asal: https://dev.to/vladimirvivien/bit-hacking-with-go

Alamat terjemahan: https://learnku.com/go/t/ 23460/bit-operation-of-go

Pembelajaran yang disyorkan: Tutorial Golang

Atas ialah kandungan terperinci Analisis ringkas operasi bit (pengendali bitwise) di Golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:learnku.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam