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

时间:2016-02-13 06:43:28

标签: c algorithm random

我需要根据2个输入值X和Y生成一个伪随机数。给定相同的X和Y值,我需要得到相同的结果。结果应介于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);
}

它给了我一个结果,但不是我正在寻找的结果。我已经从网上看到的随机事物中拼凑出来,所以不知道它是否真的有用。

2 个答案:

答案 0 :(得分:1)

借鉴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);
}

一般的想法是将xy置于各种1:1变换中并将它们混合在一起,以在整个结果中均匀地分配所有输入位(ish)。然后结果浮点数为[0,1)。我已经从可能的输出中排除了1.0,因为包含它可能是一种繁琐的。

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

答案 1 :(得分:0)

要“获得相同的结果”,PRNG状态需要至少与x,y位宽的总和一样多。 float不够广泛。

通过“相同的结果”,我认为这意味着产生了相同的数字序列。

long double 可能为您工作,但似乎您需要一个更广泛状态的新PRNG算法。