When i review a Golang project, i found some code like this, now
is Unix timestap. Call this function once every second:
//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)
}
}
Output:
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
The result is same. Why is this, what is the principle?
Actually,
int64((now - 1)/blockInterval * blockInterval
does not return the same result all the time. You will notice it changing every 10 seconds.
This is caused by integer division in Go. If you apply integer division to any two numbers, then the fractional part of the result (remainder) is dropped. For example, int(12 / 10) = 1
. In your specific case - dividing by ten, the code will drop the remainders from 1 until 9, and only increment the value when you get to the next 10.
If you'd like to increase the precision of your operations, then you can force floating point division like so float64(12)/float64(10)
.
Your problem is here:
result := int64((now-1)/blockInterval) * blockInterval
time.Now().Unix()
returns the current Unix time in seconds. So, for consecutive iterations, time.Now().Unix()
would be:
1257894001
1257894002
1257894003
But in your function, you are subtracting 1, then dividing by ten, so each of the above becomes the following because the fractional portion is dropped.
125789400
125789400
125789400
Then when you multiply by blockInterval
(10), they all become:
1257894000
1257894000
1257894000
So, result
ends up being the same. If you let it run for longer than ten seconds, you'll see result
change after 10 seconds: