登录
首页 >  Golang >  Go问答

如何检测 big.Int 是否为 0?

来源:stackoverflow

时间:2024-02-22 19:12:28 484浏览 收藏

IT行业相对于一般传统行业,发展更新速度更快,一旦停止了学习,很快就会被行业所淘汰。所以我们需要踏踏实实的不断学习,精进自己的技术,尤其是初学者。今天golang学习网给大家整理了《如何检测 big.Int 是否为 0?》,聊聊,我们一起来看看吧!

问题内容

我正在使用 big.Ints 并需要测试 0。现在,我正在使用 zero = big.NewInt(0)and Cmp(zero)==0 工作正常,但我想知道是否有没有专门针对 0 的更快的方法(我需要这个程序非常快)?


解决方案


big.Int 公开 Int.Bits() 来访问表示的原始字节,它是一个切片,并且共享相同的底层数组:不复制返回的切片。所以速度很快。它暴露于“支持缺少低级 int 功能的实现”。

完美,正是我们想要的。

0。测试 0

big.int 的文档还指出“int 的零值代表值 0”。因此,在零值(表示 0)中,切片将为空(切片的零值是 nilnil 切片的长度是 0)。我们可以简单地检查一下:

if len(i1.bits()) == 0 {
}

另请注意,有一个 Int.BitLen() 函数返回此值,该函数还声明“0 的位长度为 0”。所以我们也可以使用这个:

if i1.bitlen() == 0 {
}

让我们对这些解决方案进行基准测试:

func benchmarkcompare(b *testing.b) {
    zero := big.newint(0)
    i1 := big.newint(1)
    i2 := big.newint(0)
    for i := 0; i < b.n; i++ {
        if i1.cmp(zero) == 0 {
        }
        if i2.cmp(zero) == 0 {
        }
    }
}

func benchmarkbits(b *testing.b) {
    i1 := big.newint(1)
    i2 := big.newint(0)
    for i := 0; i < b.n; i++ {
        if len(i1.bits()) == 0 {
        }
        if len(i2.bits()) == 0 {
        }
    }
}

func benchmarkbitlen(b *testing.b) {
    i1 := big.newint(1)
    i2 := big.newint(0)
    for i := 0; i < b.n; i++ {
        if i1.bitlen() == 0 {
        }
        if i2.bitlen() == 0 {
        }
    }
}

基准测试结果:

benchmarkcompare-8      76975251            13.3 ns/op
benchmarkbits-8         1000000000           0.656 ns/op
benchmarkbitlen-8       1000000000           1.11 ns/op

获取位并将切片长度与 0 进行比较比与表示 0 的另一个 big.int 进行比较要快 20 倍,使用 int.bitlen()快 10 倍

1。测试 1

可以进行类似的操作来测试 big.int 值是否等于 1,但可能不如测试零快:0 是最特殊的值。它的内部表示是一个 nil 切片,任何其他值都需要一个非 nil 切片。另外:0还有一个特殊的属性:它的绝对值是它本身。

这个绝对值属性很重要,因为 int.bits() 返回绝对值。因此,在非零值的情况下,仅检查位片是不够的,因为它不携带符号信息。

所以对1的测试可以通过检查bits内容是否代表1,并且符号是否为正来实现:

func isone(i *big.int) bool {
    bits := i.bits()
    return len(bits) == 1 && bits[0] == 1 && i.sign() > 0
}

让我们对此进行基准测试,并将数字与 one := big.newint(1) 进行比较:

func benchmarkcompareone(b *testing.b) {
    one := big.newint(1)
    i1 := big.newint(0)
    i2 := big.newint(1)
    i3 := big.newint(2)
    for i := 0; i < b.n; i++ {
        if i1.cmp(one) == 0 {
        }
        if i2.cmp(one) == 0 {
        }
        if i3.cmp(one) == 0 {
        }
    }
}

func benchmarkbitsone(b *testing.b) {
    i1 := big.newint(0)
    i2 := big.newint(1)
    i3 := big.newint(2)
    for i := 0; i < b.n; i++ {
        if isone(i1) {
        }
        if isone(i2) {
        }
        if isone(i3) {
        }
    }
}

基准测试结果:

BenchmarkCompareOne-8       58631458            18.9 ns/op
BenchmarkBitsOne-8          715606629            1.76 ns/op

还不错!我们测试 1 的方法再次快了 10 倍

今天关于《如何检测 big.Int 是否为 0?》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

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