この記事では、Golang のビット演算を深く理解し、各演算子の詳細な事例とその使用方法を紹介します。
コンピュータのメモリが高価で処理能力が限られていた古き良き時代には、情報を処理するためにハッカースタイルのビット演算を使用することが好まれていた方法でした(場合によっては、こちらです)。今日に至るまで、ビット演算の直接使用は、低レベルのシステム プログラミング、グラフィックス処理、暗号化など、多くのコンピューティング分野で不可欠な部分となっています。 [関連する推奨事項: Go ビデオ チュートリアル ]
Go プログラミング言語は、次のビット単位の演算子をサポートしています:
& bitwise AND | bitwise OR ^ bitwise XOR &^ AND NOT > right shift
この記事の残りの部分では、各演算子とその使用方法について詳しく説明します。それ。
& 演算子
Go では、&
演算子は 2 つの整数オペランドに対して次の演算を実行します: ビット AND
の操作。 AND
演算には次のプロパティがあります。
Given operands a, b AND(a, b) = 1; only if a = b = 1 else = 0
AND
この演算子には、整数データのビットを選択的に 0 にクリアするという優れた効果があります。たとえば、&
演算子を使用して、最後の 4 つの最下位ビット (LSB) をすべて 0 にクリア (設定) できます。
func main() { var x uint8 = 0xAC // x = 10101100 x = x & 0xF0 // x = 10100000 }
すべてのビット演算は、省略された代入形式をサポートしています。たとえば、前の例は次のように書き換えることができます。
func main() { var x uint8 = 0xAC // x = 10101100 x &= 0xF0 // x = 10100000 }
もう 1 つの巧妙なトリックは、&
演算を使用して、数値が奇数か偶数かをテストできることです。その理由は、数値の最下位ビットが 1 の場合、それは奇数であるためです。数値と 1 を使用して &
演算を実行し、次に AND
演算を 1 で実行できます。結果が 1 の場合、元の数値は奇数です
import ( "fmt" "math/rand" ) func main() { for x := 0; x <p>上記の例を <a href="https://play.golang.org/p/2mTNOtioNM" target="_blank">Playground で実行します</a></p><h4> <span class="header-link octicon octicon-link"></span><strong>| Operator</strong> </h4><p><code></code>|<code> 実行します整数オペランドに対するビットごとの </code> または <code> 演算。 </code> または </p> 演算子には次のプロパティがあることを思い出してください。 <p></p><pre class="brush:php;toolbar:false">Given operands a, b OR(a, b) = 1; when a = 1 or b = 1 else = 0
ビットごとの
または 演算子を使用して、特定の整数の個々のビットを選択的に設定できます。たとえば、次の例では、ビット単位の
または を使用して、例の番号の 3 番目、7 番目、および 8 番目のビット (下位ビットから上位ビット (MSB) まで) を 1 に設定します。 func main() { var a uint8 = 0 a |= 196 fmt.Printf("%b", a) } // 打印结果 11000100 ^^ ^例はゴルフ練習場で実行できます。
または
演算は、ビット マスキング手法を使用して特定の整数に任意のビットを設定する場合に便利です。たとえば、前のプログラムを拡張して、変数
a
func main() { var a uint8 = 0 a |= 196 a |= 3 fmt.Printf("%b", a) } // 打印结果 11000111サンプルは、練習フィールドで実行できます。
前のプログラムでは、10 進数の 196 をビットごとに設定する必要があるだけでなく、下位ビットの 10 進数の 3 も設定する必要があります。続行して (
または
ビット操作の構成の使用法
ここで、
AND(a, 1) = a の場合および a = 1 の場合にのみ確認してください。 。この機能を使用して、設定ビットの値を問い合わせることができます。たとえば、上記のコード
a & 196 は、これらのビットの値が
a に存在するため、196 を返します。したがって、
OR と
AND
次のソース コード スニペットは、この操作を示しています。関数
procstr は文字列の内容を変換します。 2 つのパラメータが必要です: 1 つ目の
str は変換する文字列で、2 つ目の
conf
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 プレイグラウンドでコードを実行します。<p><code>上記の </code>procstr("HELLO PEOPLE!", LOWER|REV|CAP)<code> メソッドは文字列を小文字に変換します。次に、文字列を反転し、最後に文字列内の単語の最初の文字を大文字にします。この機能は、</code>conf</p> の 2 桁目、3 桁目、4 桁目を 14 に設定することで実現されます。次に、コードは連続する if ステートメント ブロックを使用してこれらのビット操作を取得し、対応する文字列変換を実行します。 <h4> <span class="header-link octicon octicon-link"></span><strong>#^ 演算子 </strong> </h4>#Go では、ビットごとの <p>#XOR<code> 演算は </code><code># を使用して実行されます。急行。 </code>XOR<code> 演算子には次の特性があります。 </code></p><pre class="brush:php;toolbar:false">Given operands a, b XOR(a, b) = 1; only if a != b else = 0
XOR 演算 のこの特性は、バイナリ ビットの 1 つの値を別の値に変更するために使用できます。たとえば、16 進値が与えられた場合、次のコードを使用して、値の最初の 8 ビット (MSB から開始) を切り替えることができます。
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) )为 <code>true
的时候,两个整数 a,b 具有相同的符号,如下面的程序所示:
func main() { a, b := -12, 25 fmt.Println(&amp;amp;quot;a and b have same sign?&amp;amp;quot;, (a ^ b) &amp;amp;gt;= 0) }
在 Go 的 Playground运行代码。
当执行上面这个程序的时候,将会打印出:a and b have same sign? false
。在 Go Playground 上修改程序里 a ,b 的符号,以便看到不同的结果。
^ 作为取反位运算符 (非)
不像其他语言 (c/c++,Java,Python,Javascript,等), Go 没有专门的一元取反位运算符。取而代之的是,XOR
运算符 ^
,也可作为一元取反运算符作用于一个数字。对于给定位 x,在 Go 中 x = 1 ^ x 可以翻转该位。在以下的代码段中我们可以看到使用 ^a
获取变量 a
的取反值的操作。
func main() { var a byte = 0x0F fmt.Printf(&amp;amp;quot;%08b\n&amp;amp;quot;, a) fmt.Printf(&amp;amp;quot;%08b\n&amp;amp;quot;, ^a) } // 打印结果 00001111 // var a 11110000 // ^a
在练习场中可以运行范例。
&amp;amp;^ 操作符
&amp;amp;^
操作符意为 与非
,是 与
和 非
操作符的简写形式,它们定义如下。
Given operands a, b AND_NOT(a, b) = AND(a, NOT(b))
如果第二个操作数为 1 那么它则具有清除第一个操作数中的位的趣味特性。
AND_NOT(a, 1) = 0; clears a AND_NOT(a, 0) = a;
接下来的代码片段使用 AND NOT
操作符,将变量值1010 1011
变为 1010 0000
,清除了操作数上的低四位。
func main() { var a byte = 0xAB fmt.Printf(&amp;amp;quot;%08b\n&amp;amp;quot;, a) a &amp;amp;amp;^= 0x0F fmt.Printf(&amp;amp;quot;%08b\n&amp;amp;quot;, a) } // 打印: 10101011 10100000
在练习场中运行范例。
> 操作符
与其他 C 的衍生语言类似, Go 使用 和 <code>>>
来表示左移运算符和右移运算符,如下所示:
Given integer operands a and n, a &amp;amp;gt; n; shifts all bits in a to the right n times
例如,在下面的代码片段中变量 a
(00000011
)的值将会左移位运算符分别移动三次。每次输出结果都是为了说明左移的目的。
func main() { var a int8 = 3 fmt.Printf(&amp;amp;quot;%08b\n&amp;amp;quot;, a) fmt.Printf(&amp;amp;quot;%08b\n&amp;amp;quot;, a&amp;amp;lt;p&amp;amp;gt;在 &amp;amp;lt;a href=&amp;amp;quot;https://play.golang.org/p/_lhE8OoZxY&amp;amp;quot; target=&amp;amp;quot;_blank&amp;amp;quot;&amp;amp;gt;Playground&amp;amp;lt;/a&amp;amp;gt; 运行代码&amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;p&amp;amp;gt;注意每次移动都会将低位右侧补零。相对应,使用右移位操作符进行运算时,每个位均向右方移动,空出的高位补零,如下示例 (有符号数除外,参考下面的算术移位注释)。&amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;pre class=&amp;amp;quot;brush:php;toolbar:false&amp;amp;quot;&amp;amp;gt;func main() { var a uint8 = 120 fmt.Printf(&amp;amp;quot;%08b\n&amp;amp;quot;, a) fmt.Printf(&amp;amp;quot;%08b\n&amp;amp;quot;, a&amp;amp;gt;&amp;amp;gt;1) fmt.Printf(&amp;amp;quot;%08b\n&amp;amp;quot;, a&amp;amp;gt;&amp;amp;gt;2) } // 打印: 01111000 00111100 00011110
在 练习场中可以运行范例。
可以利用左移和右移运算中,每次移动都表示一个数的 2 次幂这个特性,来作为某些乘法和除法运算的小技巧。例如,如下代码中,我们可以使用右移运算将 200
(存储在变量 a 中)除以 2 。
func main() { a := 200 fmt.Printf(&amp;amp;quot;%d\n&amp;amp;quot;, a&amp;amp;gt;&amp;amp;gt;1) } // 打印: 100
在 练习场 中可以运行范例。
或是通过左移 2 位,将一个数乘以4:
func main() { a := 12 fmt.Printf(&amp;amp;quot;%d\n&amp;amp;quot;, a&amp;amp;lt;p&amp;amp;gt;在 &amp;amp;lt;a href=&amp;amp;quot;https://play.golang.org/p/xuJRcKgMVV&amp;amp;quot; target=&amp;amp;quot;_blank&amp;amp;quot;&amp;amp;gt;练习场&amp;amp;lt;/a&amp;amp;gt; 中可以运行范例。&amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;p&amp;amp;gt;位移运算符提供了有趣的方式处理二进制值中特定位置的值。例如,下列的代码中,&amp;amp;lt;code&amp;amp;gt;|&amp;amp;lt;/code&amp;amp;gt; 和 &amp;amp;lt;code&amp;amp;gt; 用于设置变量 &amp;amp;lt;code&amp;amp;gt;a&amp;amp;lt;/code&amp;amp;gt; 的第三个 bit 位。&amp;amp;lt;/code&amp;amp;gt;&amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;pre class=&amp;amp;quot;brush:php;toolbar:false&amp;amp;quot;&amp;amp;gt;func main() { var a int8 = 8 fmt.Printf(&amp;amp;quot;%08b\n&amp;amp;quot;, a) a = a | (1&amp;amp;lt;p&amp;amp;gt;可以在 &amp;amp;lt;a href=&amp;amp;quot;https://play.golang.org/p/h7WoP7ieuI&amp;amp;quot; target=&amp;amp;quot;_blank&amp;amp;quot;&amp;amp;gt;练习场&amp;amp;lt;/a&amp;amp;gt; 中运行代码示例。&amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;p&amp;amp;gt;或者,您可以组合位移运算符和 &amp;amp;lt;code&amp;amp;gt;&amp;amp;amp;&amp;amp;lt;/code&amp;amp;gt; 测试是否设置了第n位,如下面示例所示:&amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;pre class=&amp;amp;quot;brush:php;toolbar:false&amp;amp;quot;&amp;amp;gt;func main() { var a int8 = 12 if a&amp;amp;amp;(1&amp;amp;lt;p&amp;amp;gt;在 &amp;amp;lt;a href=&amp;amp;quot;https://play.golang.org/p/Ptc7Txk5Jb&amp;amp;quot; target=&amp;amp;quot;_blank&amp;amp;quot;&amp;amp;gt;练习场&amp;amp;lt;/a&amp;amp;gt;中运行代码。&amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;p&amp;amp;gt;使用 &amp;amp;lt;code&amp;amp;gt;&amp;amp;amp;^&amp;amp;lt;/code&amp;amp;gt; 和位移运算符,我们可以取消设置一个值的某个位。例如,下面的示例将变量 a 的第三位置为 0 :&amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;pre class=&amp;amp;quot;brush:php;toolbar:false&amp;amp;quot;&amp;amp;gt;func main() { var a int8 = 13 fmt.Printf(&amp;amp;quot;%04b\n&amp;amp;quot;, a) a = a &amp;amp;amp;^ (1 &amp;amp;lt;p&amp;amp;gt;在 &amp;amp;lt;a href=&amp;amp;quot;https://play.golang.org/p/Stjq9oOjKz&amp;amp;quot; target=&amp;amp;quot;_blank&amp;amp;quot;&amp;amp;gt;练习场&amp;amp;lt;/a&amp;amp;gt; 中运行代码。&amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;h4&amp;amp;gt; &amp;amp;lt;span class=&amp;amp;quot;header-link octicon octicon-link&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;strong&amp;amp;gt;关于算术位移运算的笔记&amp;amp;lt;/strong&amp;amp;gt; &amp;amp;lt;/h4&amp;amp;gt;&amp;amp;lt;p&amp;amp;gt;当要位移的值(左操作数)是有符号值时,Go 自动应用算术位移。在右移操作期间,复制(或扩展)二进制补码符号位以填充位移的空隙。&amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;h4&amp;amp;gt; &amp;amp;lt;span class=&amp;amp;quot;header-link octicon octicon-link&amp;amp;quot;&amp;amp;gt;&amp;amp;lt;/span&amp;amp;gt;&amp;amp;lt;strong&amp;amp;gt;概要&amp;amp;lt;/strong&amp;amp;gt; &amp;amp;lt;/h4&amp;amp;gt;&amp;amp;lt;p&amp;amp;gt;他の最新の演算子と同様に、Go はすべてのバイナリ ビット操作演算子をサポートしています。この記事では、これらの演算子を使用して実行できるさまざまなハックの例を紹介するだけです。ウェブ上には多くの記事、特に Sean Eron Anderson が書いた &amp;amp;lt;a href=&amp;amp;quot;https://graphics.stanford.edu/~seander/bithacks.html&amp;amp;quot; target=&amp;amp;quot;_blank&amp;amp;quot;&amp;amp;gt;Bit Twiddle Hacks&amp;amp;lt;/a&amp;amp;gt; が見つかります。 &amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;p&amp;amp;gt;Twitter で Vladim &amp;amp;lt;a href=&amp;amp;quot;https://twitter.com/VladimirVivien&amp;amp;quot; target=&amp;amp;quot;_blank&amp;amp;quot;&amp;amp;gt;@vladimirvivien&amp;amp;lt;/a&amp;amp;gt; をフォローしてください。 &amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;p&amp;amp;gt;Go を学習している場合は、Vladimir Vivien の Go に関する書籍 &amp;amp;lt;a href=&amp;amp;quot;https://www.packtpub.com/application-development/learning-go-programming&amp;amp;quot; target=&amp;amp;quot;_blank&amp;amp;quot;&amp;amp;gt;Learning Go Programming&amp;amp;lt;/a&amp;amp;gt; を読んでください。 &amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;p&amp;amp;gt;この記事はもともと著者の Vladimir Vivien によって Medium で &amp;amp;lt;a href=&amp;amp;quot;https://medium.com/learning-the-go-programming-language/bit-hacking-with-go-e0acee258827#.2hof13ia5&amp;amp;quot; target=&amp;amp;quot;_blank&amp;amp;quot;&amp;amp;gt;Bit Hacking with Go&amp;amp;lt;/a&amp;amp;gt; として公開されたものです。 &amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;blockquote&amp;amp;gt;&amp;amp;lt;p&amp;amp;gt;英語の元のアドレス: https://dev.to/vladimirvivien/bit-hacking-with-go&amp;amp;lt;/p&amp;amp;gt;&amp;amp;lt;/blockquote&amp;amp;gt;&amp;amp;lt;p&amp;amp;gt;プログラミング関連の知識の詳細については、次のサイトを参照してください: &amp;amp;lt;a href=&amp;amp;quot;https://www.php.cn/course.html&amp;amp;quot; target=&amp;amp;quot;_blank&amp;amp;quot; textvalue=&amp;amp;quot;编程视频&amp;amp;quot;&amp;amp;gt;プログラミングビデオ&amp;amp;lt;/a&amp;amp;gt;! ! &amp;amp;lt;/p&amp;amp;gt;
以上がGolangのビット演算を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

go语言有缩进。在go语言中,缩进直接使用gofmt工具格式化即可(gofmt使用tab进行缩进);gofmt工具会以标准样式的缩进和垂直对齐方式对源代码进行格式化,甚至必要情况下注释也会重新格式化。

go语言叫go的原因:想表达这门语言的运行速度、开发速度、学习速度(develop)都像gopher一样快。gopher是一种生活在加拿大的小动物,go的吉祥物就是这个小动物,它的中文名叫做囊地鼠,它们最大的特点就是挖洞速度特别快,当然可能不止是挖洞啦。

闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。 换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。 闭包会随着函数的创建而被同时创建。

本篇文章带大家了解一下golang 的几种常用的基本数据类型,如整型,浮点型,字符,字符串,布尔型等,并介绍了一些常用的类型转换操作。

go语言需要编译。Go语言是编译型的静态语言,是一门需要编译才能运行的编程语言,也就说Go语言程序在运行之前需要通过编译器生成二进制机器码(二进制的可执行文件),随后二进制文件才能在目标机器上运行。

是,TiDB采用go语言编写。TiDB是一个分布式NewSQL数据库;它支持水平弹性扩展、ACID事务、标准SQL、MySQL语法和MySQL协议,具有数据强一致的高可用特性。TiDB架构中的PD储存了集群的元信息,如key在哪个TiKV节点;PD还负责集群的负载均衡以及数据分片等。PD通过内嵌etcd来支持数据分布和容错;PD采用go语言编写。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

Dreamweaver Mac版
ビジュアル Web 開発ツール

ホットトピック



