Golang中的Popcount实现、ARGV参数解析与线程计数探讨

Golang中的Popcount实现、ARGV参数解析与线程计数探讨 我已经搜索过这些内容,但尚未找到确切的答案。 我需要这些 Crystal 代码片段的 Go 语言翻译。

A. Go 中的 popcount 或与 Crystal 等效的功能。

seg[0..(kn - 1) >> s].each { |m| cnt += (1 << s) - m.popcount }

Go 会报错。它是否有 popcount 函数?

for m = range seg[0..(kn - 1) >> s] { cnt += (1 << s) - popcount(m)

B. 打印 CPU 线程数

puts "threads = #{System.cpu_count}"

Go 中如何实现?

fmt.Printf("threads = %d\n", ???)

C. 从命令行读取一个或两个 64 位无符号数,类似于 Crystal 中的做法。

end_num   = {ARGV[0].to_u64, 3}.max
start_num = ARGV.size > 1 ? {ARGV[1].to_u64, 3}.max : 3
start_num, end_num = end_num, start_num if start_num > end_num

Go 中如何实现? - 如何获取|使用 ARGV 并将值转换为 uint|64,并取它与 3 之间的最大值。

end_num := math.Max(unit64(ARGV[0]), 3)
if len(ARGV) > 1 {start_num := math.Max(unit64(ARGV[1]), 3}} else {start_num := 3}
if start_num > end_num { start_num, end_num = end_num, start_num }

更多关于Golang中的Popcount实现、ARGV参数解析与线程计数探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复
  1. 我花了一些时间才弄明白“popcount”是什么,弄清楚之后,答案就很明显了:math/bits.OnesCount*()
  2. 如果我没理解错的话,你想要的是 runtime.NumCPU()
  3. 要读取参数,可以使用 flag 包,或者直接访问 os.Args 并配合 strconv 包。
func main() {
    fmt.Println("hello world")
}

更多关于Golang中的Popcount实现、ARGV参数解析与线程计数探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我已经搜索过这些内容了。

参加 Go 语言之旅

A. math/bits B. runtime C. strconv, os, 和 flag

以下是针对您问题的Go语言实现:

A. Popcount实现

Go标准库的math/bits包提供了popcount功能:

package main

import (
    "fmt"
    "math/bits"
)

func main() {
    // 示例:计算popcount
    var m uint = 0b101101 // 二进制45
    cnt := bits.OnesCount(m) // 返回4(有4个1)
    fmt.Printf("popcount of %d = %d\n", m, cnt)
    
    // 针对不同位宽的popcount
    var m8 uint8 = 0b11110000
    var m16 uint16 = 0xFFFF
    var m32 uint32 = 0xFFFFFFFF
    var m64 uint64 = 0xFFFFFFFFFFFFFFFF
    
    fmt.Printf("OnesCount8: %d\n", bits.OnesCount8(m8))
    fmt.Printf("OnesCount16: %d\n", bits.OnesCount16(m16))
    fmt.Printf("OnesCount32: %d\n", bits.OnesCount32(m32))
    fmt.Printf("OnesCount64: %d\n", bits.OnesCount64(m64))
    
    // 您的代码片段翻译
    // 假设 seg 是 []uint 类型,kn 和 s 是整数
    var seg []uint
    var kn, s int
    var cntTotal uint
    
    // 原始Crystal代码的Go翻译
    // seg[0..(kn - 1) >> s].each { |m| cnt += (1 << s) - m.popcount }
    limit := (kn - 1) >> s
    if limit > len(seg) {
        limit = len(seg)
    }
    for i := 0; i < limit; i++ {
        cntTotal += (1 << s) - uint(bits.OnesCount(seg[i]))
    }
}

B. 获取CPU线程数

package main

import (
    "fmt"
    "runtime"
)

func main() {
    // 获取逻辑CPU核心数
    threads := runtime.NumCPU()
    fmt.Printf("threads = %d\n", threads)
    
    // 设置最大使用的CPU核心数
    runtime.GOMAXPROCS(threads)
}

C. 命令行参数解析

package main

import (
    "fmt"
    "math"
    "os"
    "strconv"
)

func main() {
    // 获取命令行参数
    args := os.Args[1:] // os.Args[0] 是程序名
    
    var endNum, startNum uint64
    
    // 解析第一个参数
    if len(args) > 0 {
        if val, err := strconv.ParseUint(args[0], 10, 64); err == nil {
            endNum = uint64(math.Max(float64(val), 3))
        } else {
            endNum = 3
        }
    } else {
        endNum = 3
    }
    
    // 解析第二个参数
    if len(args) > 1 {
        if val, err := strconv.ParseUint(args[1], 10, 64); err == nil {
            startNum = uint64(math.Max(float64(val), 3))
        } else {
            startNum = 3
        }
    } else {
        startNum = 3
    }
    
    // 确保 startNum <= endNum
    if startNum > endNum {
        startNum, endNum = endNum, startNum
    }
    
    fmt.Printf("start_num = %d, end_num = %d\n", startNum, endNum)
    
    // 更简洁的实现方式
    if len(args) > 0 {
        if val, err := strconv.ParseUint(args[0], 10, 64); err == nil && val > 3 {
            endNum = val
        }
    }
    
    if len(args) > 1 {
        if val, err := strconv.ParseUint(args[1], 10, 64); err == nil && val > 3 {
            startNum = val
        }
    }
    
    if startNum > endNum {
        startNum, endNum = endNum, startNum
    }
}

完整示例

package main

import (
    "fmt"
    "math/bits"
    "runtime"
    "strconv"
    "os"
)

func main() {
    // 1. Popcount示例
    num := uint(12345)
    popcnt := bits.OnesCount(num)
    fmt.Printf("Popcount of %d: %d\n", num, popcnt)
    
    // 2. CPU线程数
    fmt.Printf("threads = %d\n", runtime.NumCPU())
    
    // 3. 命令行参数处理
    args := os.Args[1:]
    var endNum, startNum uint64 = 3, 3
    
    if len(args) > 0 {
        if val, err := strconv.ParseUint(args[0], 10, 64); err == nil && val > 3 {
            endNum = val
        }
    }
    
    if len(args) > 1 {
        if val, err := strconv.ParseUint(args[1], 10, 64); err == nil && val > 3 {
            startNum = val
        }
    }
    
    if startNum > endNum {
        startNum, endNum = endNum, startNum
    }
    
    fmt.Printf("Range: %d to %d\n", startNum, endNum)
}

这些实现直接对应您提到的Crystal代码功能,使用了Go标准库中的相应包和函数。

回到顶部