为什么Go的结果相同?

时间:2019-01-16 03:17:43

标签: go math

当我审查Golang项目时,我发现了一些类似这样的代码, now是Unix时间戳。每秒调用一次此函数:

//main.go
func PrevSlot(now int64) int64 {
    // now = time.Now().Unix()
    var blockInterval = int64(10)

    result := int64((now-1)/blockInterval) * blockInterval // why result is same ?
    plog.Println("PrevSlot:", int64(result), int64((now-1)/blockInterval), now)
    return result
}


func main() {
    ticker := time.NewTicker(1 * time.Second)
    for {
        <-ticker.C

        now := time.Now().Unix()
        PrevSlot(now)
    }

}

输出:

2019-01-16 10:58:31.668597 I | dpos.go: PrevSlot: 1547607510 154760751 1547607511
2019-01-16 10:58:32.668649 I | dpos.go: PrevSlot: 1547607510 154760751 1547607512
2019-01-16 10:58:33.668568 I | dpos.go: PrevSlot: 1547607510 154760751 1547607513
2019-01-16 10:58:34.668572 I | dpos.go: PrevSlot: 1547607510 154760751 1547607514
2019-01-16 10:58:35.668547 I | dpos.go: PrevSlot: 1547607510 154760751 1547607515

结果是相同的。为什么会这样,原理是什么?

2 个答案:

答案 0 :(得分:3)

实际上,

int64((now - 1)/blockInterval * blockInterval

不会一直返回相同的结果。您会注意到它每10秒更改一次。

这是由于Go中的整数除法引起的。如果对任何两个数字应用整数除法,则结果的小数部分(余数)将被删除。例如,int(12 / 10) = 1。在您的特定情况下-除以10,代码会将余数从1减到9,并且仅在到达下一个10时才递增该值。

如果您想提高操作的精度,则可以像float64(12)/float64(10)这样强制浮点除法。

答案 1 :(得分:2)

您的问题在这里:

result := int64((now-1)/blockInterval) * blockInterval

time.Now().Unix()返回当前Unix时间。因此,对于连续的迭代,time.Now().Unix()将是:

1257894001
1257894002
1257894003

但是在您的函数中,您要减去1,然后除以10,因此,由于除去了小数部分,因此上述每个内容都变成了以下内容。

125789400
125789400
125789400

然后,当您乘以blockInterval(10)时,它们全部变为:

1257894000
1257894000
1257894000

因此,result最终是相同的。如果您让它运行超过十秒钟,那么您将在10秒钟后看到result更改:

https://play.golang.org/p/LgPtHwjwlC1