如何将随机整数转换为统一的实数[0,1 [分布

时间:2014-05-27 07:37:30

标签: c++ random distribution

在维基百科上,我找到了以下random number generator

#include <stdint.h>

/* The state must be seeded so that it is not everywhere zero. */

uint64_t s[ 2 ];

uint64_t next(void) { 
    uint64_t s1 = s[ 0 ];
    const uint64_t s0 = s[ 1 ];
    s[ 0 ] = s0;
    s1 ^= s1 << 23;
    return ( s[ 1 ] = ( s1 ^ s0 ^ ( s1 >> 17 ) ^ ( s0 >> 26 ) ) ) + s0;
}

现在,当实现时,(使用s [0]和s 1的随机种子),这很好用,但输出如下数字:

2318509732609079156, 5455176535758408500, 14446583927462861784, 3420274542024626201, etc.

我现在的问题是:如何将这些数字转换为统一的实数分布[0,1 [,即包含0和排除1?

2 个答案:

答案 0 :(得分:3)

在C ++ 11中,有一种方法可以在std::uniform_real_distribution的间隔内生成均匀分布的数字:

// uniform_real_distribution
#include <iostream>
#include <random>

int main()
{
  std::default_random_engine generator;
  std::uniform_real_distribution<double> distribution(0.0,1.0);
  double random_number_in_01 = distribution(generator);

  return 0;
} 

答案 1 :(得分:2)

假设您想要double结果,只需将随机生成器的结果转换为double并除以最大值(即2 ^ 64):

double result = next() / (double) std::numeric_limits<uint64_t>::max();

请注意,转换为64位实数值时可能会丢失一些精度,因此值可能不会完全均匀分布。如果这对您的申请很重要,您就不应该使用此代码......

编辑:抱歉,这也可能导致值1。一个简单的解决方法是重复此操作,直到值不是1,或确保next()永远不会返回std::numeric_limits<uint64_t>::max()

编辑:更简单,受到40two的回答的启发:使用随机生成器调用std :: uniform_real_distribution:

std::uniform_real_distribution<double> distribution(0.0,1.0);
double random_number_in_01 = distribution(next);