IdGenerator icon indicating copy to clipboard operation
IdGenerator copied to clipboard

看了下go的代码用的加法返回geneid可能有bug

Open molixiaoge opened this issue 1 year ago • 3 comments

看到的源码是这样写的,使用加法返回拼接的位数

// 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

molixiaoge avatar Feb 01 '24 10:02 molixiaoge

一般来说,加法和或的运算结果,确实可能不一样。 但是,在本算法满足条件:_TimestampShift = (WorkerIdBitLength + SeqBitLength) 时,加与或结果是一致的。 至于左移导致溢出的问题,这是理论上存在的,所以算法有“时长限制”,在时限范围内,不会溢出。 默认配置时限7.1万年,具体的,参考readme。

yitter avatar Feb 05 '24 07:02 yitter

好的,使用加法的目的是什么,比或更快么?

molixiaoge avatar Feb 06 '24 02:02 molixiaoge