在Swift中为给定范围内的RN实施PRNG xoshiro256 +?

时间:2018-05-28 04:42:02

标签: swift algorithm math random

基于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,从那里我需要转换为双重某种方式? 我此时实际上已经输了。

1 个答案:

答案 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]范围内具有最高可实现精度的结果。