Go 移位运算分析

Go 移位运算是一个效率很高的计算方式,根据场景进行使用,有时可以达到“出奇制胜”的效果。

在 《Go 程序设计语言》里是这样描述移位运算的:“左移以 0 填补右边空位,无符号整数右移同样以 0 填补左边空位,但有符号数的右移操作是按符号位的值填补空位。因此,请注意,如果将整数以位模式处理,须使用无符号整型”。

这里的意思很明确,如果不是无符号数,最好不要用移位运算,那么,到底是为什么呢?“有符号数的右移操作是按符号位的值填补空位”又是什么意思呢?

首先,我们看左移:

package main
import (
    "fmt"

    "github.com/imroc/biu" // 这里为了方便对比,引入第三方库
)

func main() {
    var i int8 = -9
    fmt.Println("original:", i)
    fmt.Printf("%s\\n", biu.ToBinaryString(i))
    r := i << 2
    fmt.Printf("%s\\n", biu.ToBinaryString(r))
    fmt.Println("result:", r)
}

/* 结果:
original: -9
11110111
11011100
result: -36
*/

完全符合预期,接着我们看右移:

package main
import (
    "fmt"

    "github.com/imroc/biu" // 这里为了方便对比,引入第三方库
)

func main() {
    var i int8 = -9
    fmt.Println("original:", i)
    fmt.Printf("%s\\n", biu.ToBinaryString(i))
    r := i >> 2
    fmt.Printf("%s\\n", biu.ToBinaryString(r))
    fmt.Println("result:", r)
}

/* 结果:
original: -9
11110111
11111101
result: -3
*/

纳尼?发生了什么?这里,其实发生了如下过程:

  1. 对 i 取补码,得到 00001001。
  2. 右移 2 位,得到 00000010。
  3. 再次取补码,得到 11111101。

那么,11111101 又是怎样得到 -3 值的,很简单,保留符号位,再次取补码就可以了,最后得到 1000011。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容