我使用简单的Linear Congruential Generator来生成随机数。问题是,结果表现不一致取决于我是否使用Floats
(在某些语言中称为Numbers
)或Ints
// Variable definitions
var _seed:int = 1;
const MULTIPLIER:int = 48271;
const MODULUS:int = 2147483647; // 0x7FFFFFFF (31 bit integer)
// Inside the function
return _seed = ((_seed * MULTIPLIER) % MODULUS) & MODULUS;
我遇到困难的部分是(_seed * MULTIPLIER)
部分。如果_seed
和MULTIPLIER
为Ints,则会int*int
乘法,并且大多数语言会产生int
。问题是,如果int
太大,结果值将被截断。
这是整数溢出行为"应该完成"在RNG中,还是应该在乘法之前将_seed
和MULTIPLIER
转换为Floats以便允许更大的变量?
答案 0 :(得分:1)
LCG是用整数运算实现的,因为浮点运算只是近似的 - 浮点实现将偏离整数实现,并且不会为发生器产生完整周期。即使是双精度也只有52个尾数位,这比存储两个32位整数的乘积所需的精度要低。使用模运算,它是重要的低位,并且它们有可能被砍掉。
解决方案:
您应该使用64位整数进行中间算术,然后 在模运算之后将结果转换回/转换为32位。
明确地将乘法分解为低位/高位 组件,然后在模运算后重新组合它们。 这就是Schrage在相对受欢迎(当时)的LCG中所做的this portable FORTRAN implementation。