基于 2 个输入的伪随机数生成器

Jus*_*808 0 c random algorithm

我需要根据 2 个输入值 X 和 Y 生成一个伪随机数。给定相同的 X 和 Y 值,我需要得到相同的结果。结果应介于 0 和 1 之间(含 0 和 1)。

到目前为止我有这个:

const int a = 0x7fffffff / 48271;
const int b = 0x7fffffff % 48397;

float rand(int x, int y) {
    float seed, result;

    seed = x ^ ((y << 1) & 0x2AAAAAAA) ^ ((y >> 1) & 0x33333333);
    result = 48353 * (seed % a) - b * (seed / a);

    return (result);
}
Run Code Online (Sandbox Code Playgroud)

它给了我一个结果,但不是我想要的。我是根据网上看到的一些东西拼凑起来的,所以不知道它是否真的有什么好处。

sh1*_*sh1 5

从xxHash借用:

float rand(uint32_t x, uint32_t y) {
  /* mix around the bits in x: */
  x = x * 3266489917 + 374761393;
  x = (x << 17) | (x >> 15);

  /* mix around the bits in y and mix those into x: */
  x += y * 3266489917;

  /* Give x a good stir: */
  x *= 668265263;
  x ^= x >> 15;
  x *= 2246822519;
  x ^= x >> 13;
  x *= 3266489917;
  x ^= x >> 16;

  /* trim the result and scale it to a float in [0,1): */
  return (x & 0x00ffffff) * (1.0f / 0x1000000);
}
Run Code Online (Sandbox Code Playgroud)

总体思路是进行x各种y1:1 变换,并将它们混合在一起,以将所有输入位均匀地分布在整个结果中。然后将结果浮点为[0,1)。我已将 1.0 从可能的输出中排除,因为包含它结果有点繁琐。

与任何奇数相乘(有无符号溢出)是 1:1 变换,因为奇数都是 2 的幂的互质数(a 的范围限制uint32_t)。不幸的是,乘法仅允许低位影响高位;它不允许高位影响低位。为了弥补这一点,我们有一些x ^= x >> k术语,将高位混合到低位。