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 回复
以下是针对您问题的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标准库中的相应包和函数。


