我正在尝试为一些最大值的整数实现lagged Fibonacci伪随机数生成器。它维护一个值数组
int values[SIZE] = { /* 55 seed values */ };
并使用以下函数返回下一个值
unsigned lagfib()
{
static unsigned idx = 0;
int r = values[idx];
/* The following does not work: */
values[idx] = (values[(idx-24) % SIZE] + values[(idx-55) % SIZE])
% MAX_VALUE;
idx = (idx+1) % SIZE;
return r;
}
实际上,values
应该是一个始终满的简单环形缓冲区。减法和模数应将索引包装到数组的末尾。 SIZE
应始终至少为55,但我希望将其四舍五入到64以加快模数。
但显然,我的模数计算错了,我不知道如何修复它们。将索引类型更改为int
并不会改善事情。
(PS:是的,static
数据样式不好,但我希望这对C和C ++程序员都是可读的,因为它适用于这两种语言。)
答案 0 :(得分:3)
让我们idx = 0
和SIZE = 64
。
(idx-24) % SIZE
将是一个非常大的值(对于32位int 4294967272
),因为idx
是无符号的,因此它是无效的索引。
要获得圆形效果,您应该在 之前添加SIZE
模数:
(idx-24+SIZE) % SIZE
将为(0-24+64)%64
,评估为40
。
答案 1 :(得分:2)
如果是idx
小于24,您将转到数字范围unsigned int
的另一端。 55不是例如55的除数。 2 ^ 32,所以这不会给你正确的结果。
我可以看到两个选项:
idx
变量,分别偏移24和55。(idx - 24 + SIZE) % SIZE
。实际上,我会选择第一个选项,并通过重写增量来完全避免模数:
idx = ((SIZE-1) == idx) ? 0 : (idx+1);
这可能比计算模数更快。
答案 2 :(得分:0)
您正在使用负索引访问值。例如:
-24 % 55 == -24
所以你需要一些逻辑来包装到数组的末尾。 C / C ++不会为你做这件事。