Getting float from / dev / urandom

How to get random float value from /dev/urandom ?

If I just use the cast, saying:

 int fd = ::open("/dev/urandom", O_RDONLY); uint32_t n; read(fd, &n, sizeof(n)); float f = n; 

... I'm not sure if I have a guarantee of portability, because I do not know if significant n values ​​will be represented as f ? Is MAXUINT guaranteed to be representable as a float ?

+4
source share
3 answers

You get random bytes from / dev / urandom, but these bytes do not necessarily form a) uniformly distributed floating point values ​​or b) even legal representations of any object that you relate to. For example, on a platform that has float or ints view traps, then it will be possible that the values ​​you create will be captured by the views and you will not be able to actually use the random values ​​you created.

You just need to make sure that the implementation of your std::random_device() library allows you to access / dev / urandom (by default or by entering a string argument like std::random_device("/dev/urandom") ). Then you have a random number mechanism that you can use with, for example, std::uniform_real_distribution<float>() to get the desired distribution of random numbers.

βœ“ libstdC ++ uses / dev / urandom by default:

βœ“ lib ++ also does:

βœ— The implementation of Visual Studio does not even use deterministic RNG:

βœ“ As of VS2012, MSDN states: β€œthe values ​​created by default are not deterministic and cryptographically secure,” possibly through Windows cryptographic services.

+5
source

Random bytes can be read directly in the float (for example, float f; read(fd, &f, sizeof(f)); ); assuming IEEE-754, all bit patterns are valid (although there are two infinities and many quiet and signal NaNs). You can use ieee754.h or fpclassify.h to determine if you deleted one of them.

Of course, whether this is reasonable depends on what kind of distribution you want. Assuming that IEEE-754 float32 , you will get a uniform distribution over all ranges [0, 2 -126 ) and [2 -126 2] -125 ), [2 -125 2 -124 ), ..., [2 127 2 128 ) normals (and their negatives).

0
source

You can get the floating point of a random number by dividing the random integer by the maximum integer value.

 unsigned int RAND_MAX = 0xffffffff; // for 32 bit values unsigned int random_value = rand_function(); double rand = (double) random_value / (double) RAND_MAX; 

This random number will be between 0.0 and 1.0. If you want it to be in a certain range, do the following:

 double x = 1.0; // range start double y = 3.5; // range end double range = rand * (y - x) + x; // creates values between 1.0 and 3.5 
0
source

All Articles