2 回答

TA貢獻(xiàn)2012條經(jīng)驗(yàn) 獲得超12個(gè)贊
您需要的轉(zhuǎn)換公式是:
f(P) = (mP + s) mod n
// n = range - so for uint64 2^64
// s < range i.e. < 2^64
// m = must be coprime with n
確保mod
它在所需范圍內(nèi),s
是一個(gè)簡單的移位并且m
應(yīng)該與互質(zhì)n
。Coprime 只是意味著n
并且m
不應(yīng)該共享任何共同因素。因?yàn)?code>n是 2^64 它唯一的因素是數(shù)字2
- 所以m
基本上不應(yīng)該是偶數(shù)(即不能被 2 整除):
所以對(duì)于uint64
范圍:
這可能看起來很神奇,但您可以說服自己它適用于uint16
:
https://go.dev/play/p/EKB6SH3-SGu
(因?yàn)?code>uint64需要相當(dāng)多的資源才能運(yùn)行 :-)
更新:
對(duì)于帶符號(hào)的數(shù)字(即int64
),邏輯沒有什么不同。因?yàn)槲覀冎牢覀冇幸粋€(gè)獨(dú)特的一對(duì)一映射,uint64
其中一種方法就是將輸入和輸出從 轉(zhuǎn)換為uint64
,int64
反之亦然:
// original unsigned version
func transform(p uint64) uint64 {
return m*p + s
}
func signedTransform(p int64) int64 {
return int64(transform(uint64(p)))
}
又是一個(gè)int16證明沒有碰撞的例子:
https://go.dev/play/p/Fkw5FLMK0Fu

TA貢獻(xiàn)1865條經(jīng)驗(yàn) 獲得超7個(gè)贊
要添加到colm.anseo答案,這種映射也稱為Linear congruential generator。
X n+1 = (aX n + c) mod m
當(dāng) c ≠ 0 時(shí),對(duì)于所有種子值,正確選擇的參數(shù)允許一個(gè)等于 m 的周期。當(dāng)且僅當(dāng):
m和c互質(zhì),
a-1 可被 m 的所有質(zhì)因數(shù)整除,
如果 m 可以被 4 整除,則 a-1 可以被 4 整除。
這三個(gè)要求被稱為 Hull-Dobell 定理。
對(duì)于 64 位 LCG,Knuth 的 a=6364136223846793005 和 c=1442695040888963407 看起來不錯(cuò)。
請(qǐng)注意,LCG 映射是一對(duì)一的,它將整個(gè) [0...2 64 -1] 區(qū)域映射到自身。如果你愿意,你可以反轉(zhuǎn)它。作為RNG,它具有獨(dú)特的跳躍能力。
- 2 回答
- 0 關(guān)注
- 103 瀏覽
添加回答
舉報(bào)