gpt4 book ai didi

c - C中线性同余发生器的快速模乘模素数

转载 作者:太空狗 更新时间:2023-10-29 17:25:03 24 4
gpt4 key购买 nike

我正在尝试实现一个以梅森素数 (231-1) 作为模数的随机数生成器。以下工作代码基于几个相关帖子:

  1. How do I extract specific 'n' bits of a 32-bit unsigned integer in C?
  2. Fast multiplication and subtraction modulo a prime
  3. Fast multiplication modulo 2^16 + 1

但是,

它不适用于 uint32_t hi, lo;,这意味着我不了解问题的有符号与无符号方面。

根据上面的#2,我期待答案是 (hi+lo)。这意味着,我不明白为什么需要以下声明。

   if (x1 > r)
x1 += r + 2;
  • 有人可以澄清我困惑的根源吗?

  • 代码本身可以改进吗?

  • 生成器应该避免使用 0 或 231-1 作为种子吗?

  • 质数 (2p-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);
}

最佳答案

下面的if语句

if (x1 > r)
x1 += r + 2;

应该写成

if (x1 > r)
x1 -= r;

两个结果都是相同的模 2^31:

x1 + r + 2 = x1 + 2^31 - 1 + 2 = x1 + 2^31 + 1
x1 - r = x1 - (2^31 - 1) = x1 - 2^31 + 1

第一个解决方案溢出 int32_t 并假设从 uint64_tint32_t 的转换是模 2^31。虽然许多 C 编译器以这种方式处理转换,但这并不是 C 标准强制要求的。实际结果是实现定义的。

第二个解决方案避免了溢出并适用于 int32_tuint32_t

您还可以为 r 使用整数常量:

uint64_t r = 0x7FFFFFFF; // 2^31 - 1

或者干脆

uint64_t r = INT32_MAX;

编辑:对于形式为 2^p-k 的素数,您必须使用带 p 位的掩码并计算结果

uint32_t x1 = (k * hi + lo) % ((1 << p) - k)

如果 k * hi + lo 可以溢出 uint32_t (即 (k + 1) * (2^p - 1) >= 2^ 32),你必须使用 64 位算法:

uint32_t x1 = ((uint64_t)a * x) % ((1 << p) - k)

根据平台的不同,后者可能更快。

关于c - C中线性同余发生器的快速模乘模素数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31037094/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com