首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当我没有索引时,如何使“索引超出范围”?

当我没有索引时,如何使“索引超出范围”?
EN

Stack Overflow用户
提问于 2013-09-26 23:06:11
回答 2查看 201关注 0票数 1

长期程序员-总新手在围棋。

这是密码。这是我第一次尝试发电机。我正在尝试生成一个lfsr序列。基本上,你周围的每一次都是右转一次。如果您刚刚移出了一个1位,则使用tap值的xor。

代码语言:javascript
运行
复制
package main

import (
    "fmt"
    "math/big"
)

// lfsr returns an lfsr generator.
func lfsr(tap, start big.Int) func() big.Int {
    // Keep track of next.
    next := &start
    // The generator.
    return func() big.Int {
        // Remember where we are.
        ret := *next
        // Work out next.
        fmt.Println("next", next.String(), "bit(0)", next.Bit(0))
        // Is it currently odd?
        odd := next.Bit(0)
        // Shift right one.
        next = next.Rsh(next, 1)

        // If odd - tap!
        if odd != 0 {
            // Tap!
            next = next.Xor(next, &tap)
            fmt.Printf("Tap!", next.String())
        }

        // Return where we were.
        return ret
    }
}

func main() {
    ten := new(big.Int)
    ten.SetString("10", 32)
    f := lfsr(*ten, *ten)
    for i := 0; i < 10; i++ {
        n := f()
        fmt.Println("lfsr ", n.String())
    }
}

我得到的打印结果是:

代码语言:javascript
运行
复制
next 32 bit(0) 0
lfsr  16
next 16 bit(0) 0
lfsr  8
next 8 bit(0) 0
lfsr  4
next 4 bit(0) 0
lfsr  2
next 2 bit(0) 0
lfsr  1
next 1 bit(0) 1
Tap! 0
panic: runtime error: index out of range

我做错了什么?为什么它看起来是对的?

-令人感兴趣的-它的产出:

代码语言:javascript
运行
复制
...
next 1 bit(0) 1
Tap!%!(EXTRA string=0)panic: runtime error: index out of range

goroutine 1 [running]:
math/big.nat.string(0xc010045150, 0x1, 0x5, 0x12b23d0, 0xa, ...)
    go/src/pkg/math/big/nat.go:819 +0x67f
math/big.nat.decimalString(0xc010045150, 0x1, 0x5, 0x1, 0x1, ...)
    go/src/pkg/math/big/nat.go:731 +0x8f
math/big.(*Int).String(0x7f851e0eff40, 0xc010045150, 0x1)
    go/src/pkg/math/big/int.go:331 +0xfe
main.main()
    /tmpfs/gosandbox-94dce1ec_430947f1_6360662e_01c3d6ad_a7071d20/prog.go:41 +0x120

这是( a)略有不同,( b)暗示fmt.Println("lfsr ", n.String())是失败的原因,但我并没有更近地找出原因。

添加了

经过实验(将ten.SetString("10", 32)改为ten.SetString("10", 10)),我现在得到:

代码语言:javascript
运行
复制
lfsr  5
next 5 bit(0) 1
Tap!%!(EXTRA string=0)panic: runtime error: index out of range

现在要睡觉了-希望有人能帮忙。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-27 05:23:04

复制big.Int不安全。特别是,取消引用一个*big.Int并将它赋值给一个值是行不通的。基础数组是别名,而不是复制。因为数组可以以破坏不变量的方式变异。

ret := *next是您的bug的来源。

qOCDsO2A

代码语言:javascript
运行
复制
i := big.NewInt(1)
j := *i
fmt.Println("i:", *i, "j:", j) // i: {false [1]} j: {false [1]}
i = i.Xor(i, i)
fmt.Println("i:", *i, "j:", j) // i: {false []} j: {false [0]}
//j's state has changed, it now violates the invariants
j.String() //boom

复制big.Int的方法是ret := *new(big.Int).Set(next)。我认为应该有func Copy(n *big.Int) *big.Int来做到这一点,因为语法有点难看。此外,我将避免使用big.Int作为值,并将lfsr更改为返回指针。

工作示例http://play.golang.org/p/WEFRnGlU1H

票数 1
EN

Stack Overflow用户

发布于 2013-09-27 00:04:34

它似乎是由big.Int上的String()实现引起的。可以省略n上的String()调用,让Println知道如何打印参数本身:

代码语言:javascript
运行
复制
func main() {
    ten := new(big.Int)
    ten.SetString("10", 32)
    f := lfsr(*ten, *ten)
    for i := 0; i < 10; i++ {
        n := f()
        fmt.Println("lfsr ", n)
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19040138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档