我需要为用Java编写的编程项目实现C的drand48()
和srand48()
随机数生成器和初始化程序。在给定特定种子的情况下,程序需要模仿C中这些函数生成的伪随机数。
根据手册页:
所有功能均通过生成48位整数Xi, 根据线性同余公式:
Xn+1 = (aXn + c) mod m, where n >= 0
参数m = 2 ^ 48,因此将执行48位整数运算。 除非调用lcong48(),否则a和c的计算方式为:
a = 0x5DEECE66D c = 0xB
在下面的srand48()
实现中,我将Xi的高阶32位设置为参数seedval。根据手册页,低16位设置为任意值0x330E
。我不明白如何应用同余公式来提取随机数。任何帮助将不胜感激,谢谢!
public void srand48(long seedval) {
this.seed = seedval & 0xFFFFFFFF;
this.seed = (this.seed << 16) | 0x330E;
}
public double drand48() {
this.seed = (0x5DEECE66DL * this.seed + 0xBL) & ((1L << 48) - 1);
return this.seed;
}
调用drand48()
时出现的数字不在[0.0,1.0)范围内。有人还能解释为什么48位对于这种伪随机数生成如此重要吗?
答案 0 :(得分:2)
您的实现看起来不错。您获得的值超出范围,因为您直接返回了this.seed
。您应该先将结果标准化为0.0到1.0,然后再返回。另外,请确保this.seed
是long
。
正确的代码是:
public double drand48() {
this.seed = (0x5DEECE66DL * this.seed + 0xBL) & ((1L << 48) - 1);
return (double)this.seed / (1L << 48);
}
答案 1 :(得分:0)
请注意,在 Java 中,您的 srand48 初始值设定项方法的第一行无效。如果要将值限制为 32 位,则需要添加“L”前缀,即 0xFFFFFFFF -> 0xFFFFFFFFL