我正在尝试实现一个以梅森素数 (2 31 -1) 作为模数的随机数生成器。以下工作代码基于几个相关帖子:
然而,
它不适用于uint32_t hi, lo;
,这意味着我不了解问题的有符号与无符号方面。
基于上面的#2,我期待答案是(hi + lo)。这意味着,我不明白为什么需要以下语句。
if (x1 > r)
x1 += r + 2;
有人可以澄清我的困惑的根源吗?
代码本身可以改进吗?
生成器应该避免 0 或 2 31 -1 作为种子吗?
素数(2 p -k)的代码将如何变化?
原始代码
#include <inttypes.h>
// x1 = a*x0 (mod 2^31-1)
int32_t lgc_m(int32_t a, int32_t x)
{
printf("x %"PRId32"\n", x);
if (x == 2147483647){
printf("x1 %"PRId64"\n", 0);
return (0);
}
uint64_t c, r = 1;
c = (uint64_t)a * (uint64_t)x;
if (c < 2147483647){
printf("x1 %"PRId64"\n", c);
return (c);
}
int32_t hi=0, lo=0;
int i, p = 31;//2^31-1
for (i = 1; i < p; ++i){
r |= 1 << i;
}
lo = (c & r) ;
hi = (c & ~r) >> p;
uint64_t x1 = (uint64_t ) (hi + lo);
// NOT SURE ABOUT THE NEXT STATEMENT
if (x1 > r)
x1 += r + 2;
printf("c %"PRId64"\n", c);
printf("r %"PRId64"\n", r);
printf("\tlo %"PRId32"\n", lo);
printf("\thi %"PRId32"\n", hi);
printf("x1 %"PRId64"\n", x1);
printf("\n" );
return((int32_t) x1);
}
int main(void)
{
int32_t r;
r = lgc_m(1583458089, 1);
r = lgc_m(1583458089, 2000000000);
r = lgc_m(1583458089, 2147483646);
r = lgc_m(1583458089, 2147483647);
return(0);
}