IdGenerator
IdGenerator copied to clipboard
看了下go的代码用的加法返回geneid可能有bug
看到的源码是这样写的,使用加法返回拼接的位数
// CalcID .
func (m1 *SnowWorkerM1) CalcId(useTimeTick int64) int64 {
result := int64(useTimeTick<<m1._TimestampShift) + int64(m1.WorkerId<<m1.SeqBitLength) + int64(m1._CurrentSeqNumber)
m1._CurrentSeqNumber++
return result
}
做了简单的测试代码,发现加和或的值不一样
func main() {
var a int64 = 178438932798732984
var b int64 = 318793718938921712
fmt.Printf("a value %064b\n", a)
fmt.Printf("b value %064b\n", b)
aor := a | b
aadd := a + b
fmt.Printf("a|b value %064b\n", aor)
fmt.Printf("a+b value %064b\n", aadd)
fmt.Printf("| %d\n ", aor)
fmt.Printf("add %d\n ", aadd)
if aor != aadd {
fmt.Println("not equal")
}
}
另外发现,go做左移的时候会有溢出的问题
var workid int64 = 1234211
fmt.Printf("%064b\n", workid)
//0000000000000000000000000000000000000000000100101101010100100011
id := workid << 53
//左移53位应该是如下值 但是go运算似乎是直接用 workid*2^53次方导致溢出了
//1010010001100000000000000000000000000000000000000000000000000000
fmt.Println(id)
//-6602277053725147136
fmt.Printf("%064b", id)
//-101101110100000000000000000000000000000000000000000000000000000
一般来说,加法和或的运算结果,确实可能不一样。 但是,在本算法满足条件:_TimestampShift = (WorkerIdBitLength + SeqBitLength) 时,加与或结果是一致的。 至于左移导致溢出的问题,这是理论上存在的,所以算法有“时长限制”,在时限范围内,不会溢出。 默认配置时限7.1万年,具体的,参考readme。
好的,使用加法的目的是什么,比或更快么?