Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 有大的比特数吗?_Go_Bitcount - Fatal编程技术网

Go 有大的比特数吗?

Go 有大的比特数吗?,go,bitcount,Go,Bitcount,是否已经为big.Int编写了BitCount方法?数学/大数学似乎没有 显然,如果没有的话,我会自己写一本——有人已经写过了吗 我想要数字中的设定位数。比如。我自己把一个放在一起-注意这不考虑数字的符号。这将返回big.Int后面的原始字节的位计数 // How many bits? func BitCount(n big.Int) int { var count int = 0 for _, b := range n.Bytes() { count += in

是否已经为big.Int编写了
BitCount
方法?数学/大数学似乎没有

显然,如果没有的话,我会自己写一本——有人已经写过了吗


我想要数字中的设定位数。比如。

我自己把一个放在一起-注意这不考虑数字的符号。这将返回
big.Int
后面的原始字节的位计数

// How many bits?
func BitCount(n big.Int) int {
    var count int = 0
    for _, b := range n.Bytes() {
        count += int(bitCounts[b])
    }
    return count
}

// The bit counts for each byte value (0 - 255).
var bitCounts = []int8{
    // Generated by Java BitCount of all values from 0 to 255
    0, 1, 1, 2, 1, 2, 2, 3, 
    1, 2, 2, 3, 2, 3, 3, 4, 
    1, 2, 2, 3, 2, 3, 3, 4, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    1, 2, 2, 3, 2, 3, 3, 4, 
    2, 3, 3, 4, 3, 4, 4, 5,  
    2, 3, 3, 4, 3, 4, 4, 5, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    1, 2, 2, 3, 2, 3, 3, 4, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    4, 5, 5, 6, 5, 6, 6, 7, 
    1, 2, 2, 3, 2, 3, 3, 4, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    4, 5, 5, 6, 5, 6, 6, 7, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    4, 5, 5, 6, 5, 6, 6, 7, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    4, 5, 5, 6, 5, 6, 6, 7, 
    4, 5, 5, 6, 5, 6, 6, 7, 
    5, 6, 6, 7, 6, 7, 7, 8,
}

我自己把一个放在一起-注意这不考虑数字的符号。这将返回
big.Int
后面的原始字节的位计数

// How many bits?
func BitCount(n big.Int) int {
    var count int = 0
    for _, b := range n.Bytes() {
        count += int(bitCounts[b])
    }
    return count
}

// The bit counts for each byte value (0 - 255).
var bitCounts = []int8{
    // Generated by Java BitCount of all values from 0 to 255
    0, 1, 1, 2, 1, 2, 2, 3, 
    1, 2, 2, 3, 2, 3, 3, 4, 
    1, 2, 2, 3, 2, 3, 3, 4, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    1, 2, 2, 3, 2, 3, 3, 4, 
    2, 3, 3, 4, 3, 4, 4, 5,  
    2, 3, 3, 4, 3, 4, 4, 5, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    1, 2, 2, 3, 2, 3, 3, 4, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    4, 5, 5, 6, 5, 6, 6, 7, 
    1, 2, 2, 3, 2, 3, 3, 4, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    4, 5, 5, 6, 5, 6, 6, 7, 
    2, 3, 3, 4, 3, 4, 4, 5, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    4, 5, 5, 6, 5, 6, 6, 7, 
    3, 4, 4, 5, 4, 5, 5, 6, 
    4, 5, 5, 6, 5, 6, 6, 7, 
    4, 5, 5, 6, 5, 6, 6, 7, 
    5, 6, 6, 7, 6, 7, 7, 8,
}

仅供参考,以下解决方案比此处提供的原始解决方案更简单、更快:

func BitCountFast(z *big.Int) int {
    var count int
    for _, x := range z.Bits() {
            for x != 0 {
                    x &= x-1
                    count++
            }
    }
    return count
}
在我的机器上,它的性能比原始解决方案高出5倍:

BenchmarkBitCountFast-4 100000000           19.5 ns/op         0 B/op          0 allocs/op
BenchmarkBitCountOrig-4 20000000            96.1 ns/op        16 B/op          1 allocs/op

仅供参考,以下解决方案比此处提供的原始解决方案更简单、更快:

func BitCountFast(z *big.Int) int {
    var count int
    for _, x := range z.Bits() {
            for x != 0 {
                    x &= x-1
                    count++
            }
    }
    return count
}
在我的机器上,它的性能比原始解决方案高出5倍:

BenchmarkBitCountFast-4 100000000           19.5 ns/op         0 B/op          0 allocs/op
BenchmarkBitCountOrig-4 20000000            96.1 ns/op        16 B/op          1 allocs/op

如前所述,为了快速有效地原始访问要使用的
big.Int
的底层位。 此外,比8位查找表或简单循环更快的是使用众所周知的64位计数方法(aka)。 甚至更快,您可以使用一个使用本机的
popcount
程序集实现

如果不使用汇编,或者不满足已知设置的位很少的特殊情况,这可能是更快/最快的Go实现之一(在32位机器上,可以通过使用
uint32
并相应调整
popcount
功能来提高速度):

func位计数(n*big.Int)Int{
计数:=0
对于u,v:=范围n.位(){
计数+=popcount(uint64(v))
}
返回计数
}
//直接简单的C语言翻译https://en.wikipedia.org/wiki/Hamming_weight
func popcount(x uint64)int{
常数(
m1=0x5555//二进制:0101。。。
m2=0x3333//二进制:00110011。。
m4=0x0F0F//二进制:4个零,4个一。。。
h01=0x0101010101//256之和等于0,1,2,3的幂。。。
)
x-=(x>>1)&m1//将每2位的计数放入这2位中
x=(x&m2)+(x>>2)&m2)//将每4位的计数放入这4位中
x=(x+(x>>4))&m4//将每8位的计数放入这8位中

return int((x*h01)>>56)//返回前面提到的x+(x的左8位,以便快速有效地原始访问要使用的
big.int
的底层位。 此外,比8位查找表或简单循环更快的是使用众所周知的64位计数方法(aka)。 甚至更快,您可以使用一个使用本机的
popcount
程序集实现

如果不使用汇编,或者不满足已知设置的位很少的特殊情况,这可能是更快/最快的Go实现之一(在32位机器上,可以通过使用
uint32
并相应调整
popcount
功能来提高速度):

func位计数(n*big.Int)Int{
计数:=0
对于u,v:=范围n.位(){
计数+=popcount(uint64(v))
}
返回计数
}
//直接简单的C语言翻译https://en.wikipedia.org/wiki/Hamming_weight
func popcount(x uint64)int{
常数(
m1=0x5555//二进制:0101。。。
m2=0x3333//二进制:00110011。。
m4=0x0F0F//二进制:4个零,4个一。。。
h01=0x0101010101//256之和等于0,1,2,3的幂。。。
)
x-=(x>>1)&m1//将每2位的计数放入这2位中
x=(x&m2)+(x>>2)&m2)//将每4位的计数放入这4位中
x=(x+(x>>4))&m4//将每8位的计数放入这8位中
return int((x*h01)>>56)//返回x+(x的左8位,您现在可以使用(从Go 1.9开始)这个库来实现一些处理位相关计算的有用函数。具体地说,您可以迭代并调用函数的结果

以下是一个例子:

package main

import (
    "fmt"
    "math/big"
    "math/bits"
)

func BitCount(z *big.Int) int {
    var count int
    for _, x := range z.Bits() {
        count += bits.OnesCount(uint(x))
    }
    return count
}

func PrintBinary(z *big.Int) {
    for _, x := range z.Bits() {
        fmt.Printf("%064b\n", x)
    }
}

func main() {
    a := big.NewInt(1 << 60 - 1)
    b := big.NewInt(1 << 61 - 1)
    c := big.NewInt(0)
    c = c.Mul(a, b)

    fmt.Println("Value in binary format:")
    PrintBinary(c)
    fmt.Println("BitCount:", BitCount(c))
}
主程序包
进口(
“fmt”
“数学/大”
“数学/比特”
)
func位计数(z*big.Int)Int{
变量计数整数
对于ux:=范围z.位(){
计数+=位。一个单位(uint(x))
}
返回计数
}
func PrintBinary(z*big.Int){
对于ux:=范围z.位(){
fmt.Printf(“%064b\n”,x)
}
}
func main(){
a:=big.NewInt(1您现在可以使用(从Go 1.9开始)实现一些有用函数的库,这些函数处理与位相关的计算。具体地说,您可以遍历函数的结果并调用函数

以下是一个例子:

package main

import (
    "fmt"
    "math/big"
    "math/bits"
)

func BitCount(z *big.Int) int {
    var count int
    for _, x := range z.Bits() {
        count += bits.OnesCount(uint(x))
    }
    return count
}

func PrintBinary(z *big.Int) {
    for _, x := range z.Bits() {
        fmt.Printf("%064b\n", x)
    }
}

func main() {
    a := big.NewInt(1 << 60 - 1)
    b := big.NewInt(1 << 61 - 1)
    c := big.NewInt(0)
    c = c.Mul(a, b)

    fmt.Println("Value in binary format:")
    PrintBinary(c)
    fmt.Println("BitCount:", BitCount(c))
}
主程序包
进口(
“fmt”
“数学/大”
“数学/比特”
)
func位计数(z*big.Int)Int{
变量计数整数
对于ux:=范围z.位(){
计数+=位。一个单位(uint(x))
}
返回计数
}
func PrintBinary(z*big.Int){
对于ux:=范围z.位(){
fmt.Printf(“%064b\n”,x)
}
}
func main(){

a:=big.NewInt(1我认为如果您在这里使用
int8
而不是
int
,则缓存命中率会更高(4x?)。我认为如果您在这里使用
int8
而不是
int
,则缓存命中率会更高(4x?)缓存命中。速度更快的原因之一是返回对底层
[]big.Word
的原始访问,而分配一个新的
[]字节
。还要注意,这里的外部
for
循环可以更快地使用标准32或64位运算来计算每个
big.Word
(只是
uintpttr
)和删除嵌套循环。例如,请参阅。(注意,我已将我以前的注释转化为)我的代码速度更快的另一个原因是基准测试中使用的稀疏位集:)使用密集位集时,您的解决方案速度更快