Generating random floating-point values based on r

2019-01-25 13:47发布

Given a random source (a generator of random bit stream), how do I generate a uniformly distributed random floating-point value in a given range?

Assume that my random source looks something like:

unsigned int GetRandomBits(char* pBuf, int nLen);

And I want to implement

double GetRandomVal(double fMin, double fMax);

Notes:

  • I don't want the result precision to be limited (for example only 5 digits).
  • Strict uniform distribution is a must
  • I'm not asking for a reference to an existing library. I want to know how to implement it from scratch.
  • For pseudo-code / code, C++ would be most appreciated

8条回答
三岁会撩人
2楼-- · 2019-01-25 14:38

Here is one way of doing it.

The IEEE Std 754 double format is as follows:

[s][     e     ][                          f                         ]

where s is the sign bit (1 bit), e is the biased exponent (11 bits) and f is the fraction (52 bits).

Beware that the layout in memory will be different on little-endian machines.

For 0 < e < 2047, the number represented is

(-1)**(s)   *  2**(e – 1023)  *  (1.f)

By setting s to 0, e to 1023 and f to 52 random bits from your bit stream, you get a random double in the interval [1.0, 2.0). This interval is unique in that it contains 2 ** 52 doubles, and these doubles are equidistant. If you then subtract 1.0 from the constructed double, you get a random double in the interval [0.0, 1.0). Moreover, the property about being equidistant is preserve. From there you should be able to scale and translate as needed.

查看更多
Deceive 欺骗
3楼-- · 2019-01-25 14:43

This is probably not the answer you want, but the specification here:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3225.pdf

in sections [rand.util.canonical] and [rand.dist.uni.real], contains sufficient information to implement what you want, though with slightly different syntax. It isn't easy, but it is possible. I speak from personal experience. A year ago I knew nothing about random numbers, and I was able to do it. Though it took me a while... :-)

查看更多
登录 后发表回答