登录
首页 >  Golang >  Go问答

Golang 中的位运算

来源:stackoverflow

时间:2024-02-19 10:36:26 250浏览 收藏

有志者,事竟成!如果你在学习Golang,那么本文《Golang 中的位运算》,就很适合你!文章讲解的知识点主要包括,若是你对本文感兴趣,或者是想搞懂其中某个知识点,就请你继续往下看吧~

问题内容

我正在查看包含以下内容的代码库:

const IdLength = 20

type NodeID [IdLength]byte

func (node NodeID) PrefixLen() (ret int) {
  for i := 0; i < IdLength; i++ {
    for j := 0; j < 8; j++ {
      if (node[i] >> uint8(7 - j)) & 0x1 != 0 {
        return i * 8 + j;
      }
    }
  }
  return IdLength * 8 - 1;
}

我不太明白这里发生了什么。有人可以用例子向我解释一下吗?


解决方案


这将可变数量的字节作为输入,这些字节实际上被视为位。它返回字节流中前导 0 位的数量。假设您有这些字节:

0x00 0x00 0x05

二进制看起来像这样

00000000 00000000 00000101

这意味着函数返回 8+8+5 = 21

i 作为变量的外循环遍历所有字节,以 j 作为变量的内循环遍历该字节中的所有位。它将第 j 位从顶部向下移动到最低位,二进制和 (&) 与 0x01 屏蔽除最低位之外的所有位,然后 != 0 询问该位是否为 1 在这种情况下我们处于末尾0 前缀并返回结果。

如果在函数末尾没有提前返回,则所有字节都是 0,因此它返回该值。由于某种原因,该特殊情况不会返回 208 而是 208-1。我猜这是特定于应用程序的。我本以为它会返回全零,但结果却少了一个。

这是一个代码示例,其中输出作为注释:

package main

import "fmt"

func main() {
    fmt.Println(NodeID{0xFF}.PrefixLen()) // 0
    fmt.Println(NodeID{0x7F}.PrefixLen()) // 1
    fmt.Println(NodeID{0x3F}.PrefixLen()) // 2
    fmt.Println(NodeID{0x1F}.PrefixLen()) // 3
    fmt.Println(NodeID{0x0F}.PrefixLen()) // 4
    // ...
    fmt.Println(NodeID{0x00, 0x00, 0x05}.PrefixLen()) // 21
    // ...
    fmt.Println(NodeID{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}.PrefixLen()) // 159
    fmt.Println(NodeID{}.PrefixLen()) // 159
}

const IdLength = 20

type NodeID [IdLength]byte

func (node NodeID) PrefixLen() (ret int) {
    for i := 0; i < IdLength; i++ {
        for j := 0; j < 8; j++ {
            if (node[i]>>uint8(7-j))&0x1 != 0 {
                return i*8 + j
            }
        }
    }
    return IdLength*8 - 1
}

今天关于《Golang 中的位运算》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>