4

如何从中获取随机浮点值/dev/urandom

如果我只是使用演员表,请说:

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

...我不确定我是否有可移植性的保证,因为我不知道大的值n是否一定可以表示为f?MAXUINT 是否保证可以表示为float?

4

3 回答 3

5

您从 /dev/urandom 获得随机字节,但这些字节不一定会形成 a) 均匀分布的浮点值或 b) 甚至是您对待它们的任何对象的合法表示。例如,在具有浮点数或整数的捕获表示的平台上,您创建的值可能会捕获表示,并且您将无法实际使用您创建的随机值。

您应该简单地验证您的库的实现是否std::random_device()允许访问 /dev/urandom (默认情况下或通过使用类似的字符串std::random_device("/dev/urandom")参数std::uniform_real_distribution<float>():你想要的随机数分布。

✓ libstdc++ 默认使用 /dev/urandom:

✓ libc++ 也可以:

✗ Visual Studio 的实现甚至没有使用非确定性 RNG:

✓ 从 VS2012 开始,MSDN 声明“默认生成的值是非确定性的且在密码学上是安全的”,可能是通过 Windows 的 Cryptographic Services。

于 2012-06-26T22:47:08.017 回答
0

可以将read随机字节直接放入一个float(例如float f; read(fd, &f, sizeof(f)););假设 IEEE-754,所有位模式都是有效的(尽管有两个无穷大和许多安静和信令 NaN)。您可以使用ieee754.horfpclassify.h来确定您是否击中了其中之一。

当然,这是否合理取决于你想要什么样的分布。假设 IEEE-754 ,您将在 [0, 2 -126 ) 非正规和 [2 -126 , 2 -125 ), [2 -125 , 2 -124 ), ...float32的每个范围内得到均匀分布。 , [2 127 , 2 128 ) 法线(及其否定)。

于 2012-06-26T23:14:08.967 回答
0

您可以通过将随机整数除以最大整数值来获得随机数浮点数。

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

该随机数将介于 0.0 和 1.0 之间。如果您希望它在某个范围内,只需这样做:

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
于 2017-03-21T22:11:50.110 回答