代码之家  ›  专栏  ›  技术社区  ›  ANoobSwiftly

在给定范围内对RN执行prng xoshiro256+?

  •  0
  • ANoobSwiftly  · 技术社区  · 6 年前

    根据用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.
    

    但是在调用了“next”函数6次之后,我得到了一个错误,我猜想这是因为超过了uint64的最大限制。 这只是一个猜测。

    从这一点上,我将如何着手实现我所追求的目标?我猜我需要放弃较低的位才能继续调用“next”函数而不超过uint64,从那里我需要转换成double? 我现在真的迷路了。

    1 回复  |  直到 6 年前
        1
  •  1
  •   pjs    6 年前

    XOR不能溢出,所以您的问题在于加法。变化 let result_plus = s[0] + s[3] let result_plus = s[0] &+ s[3] (注意“&”)告诉Swift您希望在溢出时截断加法。您可以阅读苹果《Swift编程语言》一书中有关“溢出操作”的章节,了解更多详细信息。

    转换为 Double 用途:

    Double(next() >> 12) / 0x10000000000000
    

    双重的 有52个尾数位,十六进制值为2*52。这将使用 UInt64 在[0,1.0]范围内产生具有最高可实现精度的结果。