This is a creation in Article, where the information may have evolved or changed. [Cover] (Https://raw.githubusercontent.com/studygolang/gctt-images/master/go-bits/cover.png) In previous memory and processing power (CPU) is very expensive, Thus programming directly in-place becomes the preferred way to process information (and in some cases the only way). Today, direct bitwise operations are critical in the areas of underlying systems, image processing, and cryptography. The following types of operations are supported in the Go language: ' & Bit and | Bit or ^ xor or &^ and non << left shift >> right shift next we will discuss each operator in detail and give some examples of how bit manipulation can be applied. # # ' & ' operator in Go, the ' & ' operator is used to perform a bitwise AND operation between two integers. The and operation has the following characteristics: ' ' Given operands A, BAND (A, b) = 1; only if a = b = 1 else = 0//a given 2 operands a,b://if and only if both A and B are 1 o'clock, the result of operation and (A, b) is 1. Otherwise the operation and (A, b) is 0. The "and" operator is a good way to clear the specified bits of an integer to zero. In the following example, we use the ' & ' operator to zero the number after 4 bits. "' Gofunc main () {var x uint8 = 0xAC//x = 10101100 x = x & 0xF0//x = 10100000} ' All binary operators support shorthand, we can change the above example to a shorthand Formula: "' gofunc main () {var x uint8 = 0xAC//x = 10101100 x &= 0xF0//x = 10100000}" "Another trick is to use ' & ' to determine whether a number is odd or is an even number. We can use the number and value 1 to do an AND operation with ' & '. If the result is 1, that means the original number is an odd. "'" Goimport ("FMT" "Math/rand") func main () {for x: = 0; x < + × x + + num: = Rand. Int () If NuM&1 = = 1 {fmt. Printf ("%d is odd\n", num)} else {fmt. Printf ("%d is even\n", num)}} "[Run online] (Https://play.golang.org/p/2mTNOtioNM) # # ' | ' operator ' | ' is used to make a bitwise OR operation of a number. The OR operator has the following characteristics: ' ' Given operands A, BOR (A, b) = 1; When a = 1 or b = 1 else = 0//Given two operands a,b//if and only if both A and B are 0 o'clock, the operation or (a, B) returns 0. No returns 1. "We can use this feature to set the specified position in an integer to 1. In the following example, we use the OR operation to place the 3rd, 7, and 8 positions at 1. "' Gofunc main () {var a uint8 = 0 a |= 196 fmt. Printf ("%b", a)}//prints 11000100 ^^ ^ "[Running online] (HTTPS://PLAY.GOLANG.ORG/P/3VPV4D83OJ) When using mask technology on a number, OR is very useful. In the following example we can set more bits: ' ' gofunc main () {var a uint8 = 0 A |= 196 a |= 3 fmt. Printf ("%b", a)}//prints 11000111 "[Online operation] (https://play.golang.org/p/7aJLwh3y4x) In the example above, we not only have all the digits in the number 196, And the last two bits are also numbered 3 by 1. We can always do a 1 operation until all the bits are 1. # # # Use BITS as configuration information now, review ' and (a,1) = A if and only if a = 1 '. We can use this technique to query the value on the anchor. For example ' A & 196 ' will return ' 196 ' because all bits of ' 196 ' in ' A ' are placed 1. So we can use or and and to set and read the value of the configuration information. The following code completes this function. The function ' Procstr ' converts the given string. It receives two parameters: the first parameter ' str ' is a string to be converted, the second parameter ' conf ' uses the mask to specify the conversionConfiguration information. "Go const (UPPER = 1//UPPER Case LOWER = 2//LOWER Case CAP = 4//capitalizes REV = 8//Reverses) Func main () {FMT . Println (Procstr ("HELLO people!", lower| rev| CAP))}func procstr (str string, conf byte) string {//reverse 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)}//query config bits 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} ' [Online Run] (https://play.golang.org/p/4E05PQwj5q) call ' PR Ocstr ("HELLO people!", lower| rev| CAP) will convert the string to lowercase, invert and capitalize the first letter of each word. This will be done when 2nd, 3, 4 bits on ' conf ' are 1 o'clock (conf equals 14). Internally we use the IF statement to remove these bits and manipulate the strings according to the corresponding configuration. The # # ' ^ ' operator XOR operator is represented in Go with ' ^ '. XOR is an exceptional OR, it has the following characteristics: ' ' gogiven operands A, Bxor (A, b) = 1; only if a! = b else = 0//given 2 operands a,b//if and only if a!=b , the Operation XOR (A, B) returns 1. No returns 0. This implies that we can use XOR to toggle the value on the anchor. For example, given a 16-bit value, we can use the following code to toggle its first eight bits: "Go func main () {var a uint16 = 0xCEFF a ^= 0xff00//Same A = a ^ 0xff00}//a = 0x Ceff (11001110 11111111)//A ^=0xff00 (00110001 11111111) "In the previous code, the value of the bit is toggled between 0 and 1 through the XOR operation. One of the practical uses of XOR is to compare whether the two-digit sign is the same. Two digits ' A ', ' B ', if ' (a ^ b) >= 0 ' then A and B are the same number if ' (a ^ b) < 0 ' Then A and B are different. "' Gofunc Main () {A, B: = -12, FMT. Println ("A and B has same sign?", (a ^ b) >= 0)} "[Run online] (Https://play.golang.org/p/6rAPti5bXJ) when the above code execution outputs ' A and B ha ve same sign? False '. Use Go Playground to modify different symbols to see different results. # # # uses ' ^ ' as a bit non-operational unlike other languages (c/C + +, Java, Python, Javascript, etc.), Go does not have unary operators. The XOR operator ' ^ ' can be used as a unary operator to calculate the complement of a number. Given a bit ' x ', in Go ' ^x = 1 ^ x ' will reverse the x's bit. We can calculate the complement of the variable ' a ' by ' ^a '. "' Gofunc main () {var a byte = 0x0F fmt. Printf ("%08b\n", a) fmt. Printf ("%08b\n", ^a)}//prints00001111//var a11110000//^a "[Running online] (https://play.golang.org/p/5d1fQjDAIv) # # # & The ^ ' operator ' &^ ' operator is called and not. It is a use of ' and ' after the use of ' noT ' Operation shorthand. The operator is defined as follows: "' Given operands A,band_not (A, B) = and (A, not (b))//Given two operands a,b//when A=not (b) =1, Operation And_not (A, B) returns 1. Otherwise, 0 is returned. "It has an interesting feature: if the second operator returns 1. Then the bit will be cleared 0. "' And_not (A, 1) = 0; Clears Aand_not (A, 0) = A; The code snippet below uses the and not operation to Fulai Qing off the next 4 bits of ' a ' (' 1010 1011 ' to ' 1010 0000 '). "' Gofunc main () {var a byte = 0xAB fmt. Printf ("%08b\n", a) a &^= 0x0F fmt. Printf ("%08b\n", a)}//prints:1010101110100000 "[Run online] (https://play.golang.org/p/UPUlBOPRGh) # # ' << ' and ' > The > ' operator, like other C-family languages, uses ' << ' and ' >> ' to represent left or right-shift operations, defined as follows: ' ' Given integer operands A and n,a << N; Offsets all bits in a to the left n times a >> n; Offsets all bits in a to the right by N times "" For example: in the following fragment, ' A ' is shifted left 3 times using the left shift operator (' 00000011 '). The results will be printed out each time. "' Gofunc 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)}//prints:00000011000001100000110000011000 "need to be aware that each left-to-right bit will be filled with 0. Conversely, when you use the right-shift operator, the left-hand bits are filled with 0 (except for signed numbers, see the *arithmetic shifts* section later). "' GofUNC main () {var a uint8 = + FMT. Printf ("%08b\n", a) fmt. Printf ("%08b\n", a>>1) fmt. Printf ("%08b\n", a>>2)}//prints:011110000011110000011110 "Some simple use of the left and right shifts is multiplication and division, where each shift is multiplied or 2 powers apart." The following code divides 200 by 2. "' Gofunc Main () {A: = $ FMT. Printf ("%d\n", a>>1)}//prints:100 ' [Run online] (Https://play.golang.org/p/EJi0YCARun) or multiply a value by 4: ' Go func main () { A: = Fmt. Printf ("%d\n", a<<2)}//prints:48 ' [Online run] (Https://play.golang.org/p/xuJRcKgMVV) Shift operators provide a very interesting way to set a binary value. We use ' | ' and ' << ' to set the value of the ' a ' third bit. "' Gofunc main () {var a int8 = 8 fmt. Printf ("%08b\n", a) a = a | (1<<2) fmt. Printf ("%08b\n", a)}//prints:0000100000001100 "[Run online] (Https://play.golang.org/p/h7WoP7ieuI) or use ' & ' and the displacement operator to test that the nth bit is not the specified value: "' gofunc main () {var a int8 = 0 if a& (1<<2)! =" {fmt. PRINTLN ("Take action")}}//prints:take action "[Run online] (https://play.golang.org/p/Ptc7Txk5Jb) using ' &^ ' and displacement operations to give nth position 0: ' Gofunc main () {var a int8 = Fmt. Printf ("%04b\n", a) a = a &^ (1 << 2) fmt. Printf ("%04b\n", a)}//prints:11011001 "[Online Run] (https://play.golang.org/p/Stjq9oOjKz) # # # shift operator Considerations when moving a signed value, Go The displacement operation will be automatically adapted. When you shift to the right, the values on the positive and negative bits are populated on the missing bits.
via:https://medium.com/learning-the-go-programming-language/bit-hacking-with-go-e0acee258827
Author: Vladimir Vivien Translator: Saberuster proofreading: Rxcai
This article by GCTT original compilation, go language Chinese network honor launches
This article was originally translated by GCTT and the Go Language Chinese network. Also want to join the ranks of translators, for open source to do some of their own contribution? Welcome to join Gctt!
Translation work and translations are published only for the purpose of learning and communication, translation work in accordance with the provisions of the CC-BY-NC-SA agreement, if our work has violated your interests, please contact us promptly.
Welcome to the CC-BY-NC-SA agreement, please mark and keep the original/translation link and author/translator information in the text.
The article only represents the author's knowledge and views, if there are different points of view, please line up downstairs to spit groove
725 Reads