基于c:here编写的来源。
我试图在Swift中实现xoshiro256 +伪随机数生成器(PRNG)。我需要达到算法给出0到1之间的数字的点,然后我可以乘以给定的范围计数,然后移动该范围内的第一个数字。
到目前为止,我已经重写了源代码中列出的内容:
func rotl(_ x: UInt64, _ k: Int) -> UInt64 {
return (x << k) | (x >> (64 - k))
} // This is the rotating function.
var s: [UInt64] = [1,2,3,4] // I gave a seed vector of the basic 1234.
func next() -> UInt64 {
let result_plus = s[0] + s[3]
let t = s[1] << 17
s[2] ^= s[0]
s[3] ^= s[1]
s[1] ^= s[2]
s[0] ^= s[3]
s[2] ^= t
s[3] = rotl(s[3], 45)
return result_plus
} // This returns the next number in the algorithm while XORing the seed vectors for use in the next call.
但在打电话给&#34;下一个&#34;功能6次我得到一个错误,我猜测是超过UInt64的最大限制。 这只是猜测。
从这一点开始,我将如何继续实现我的目标?我猜我需要丢弃低位才能继续调用&#34; next&#34;功能不超过UInt64,从那里我需要转换为双重某种方式? 我此时实际上已经输了。
答案 0 :(得分:1)
XOR不能溢出,所以你的问题在于添加。将let result_plus = s[0] + s[3]
更改为let result_plus = s[0] &+ s[3]
(注意'&amp;')告诉Swift您希望添加截断溢出。有关更多详细信息,请参阅Apple的书“The Swift Programming Language”中的“Overflow Operators”部分。
转换为Double
使用:
Double(next() >> 12) / 0x10000000000000
A Double
有52个尾数位,十六进制值为2 ** 52。这使用UInt64
的高52位来产生[0,1.0]范围内具有最高可实现精度的结果。