如何从/dev/urandom
获取随机浮动值?
如果我只是使用演员,说:
int fd = ::open("/dev/urandom", O_RDONLY);
uint32_t n;
read(fd, &n, sizeof(n));
float f = n;
...我不确定我是否有可移植性保证,因为我不知道n
的大值是否必须代表f
? MAXUINT是否可以表示为float
?
答案 0 :(得分:5)
您从/ dev / urandom获得随机字节,但这些字节不一定会形成a)均匀分布的浮点值,或b)甚至是您将其视为对象的任何对象的合法表示。例如,在具有浮点数或整数的陷印表示的平台上,您创建的值可能会捕获表示,并且您将无法实际使用您创建的随机值。
您应该只是验证您的库的std::random_device()
实现允许访问/ dev / urandom(默认情况下或通过使用字符串参数,如:std::random_device("/dev/urandom")
。然后您有一个随机数引擎可以与std::uniform_real_distribution<float>()
一起使用,以获得所需的随机数分布。
✓libstdc++默认使用/ dev / urandom:
✓libc++同样如此:
✗VisualStudio的实现甚至没有使用非确定性RNG:
✓自VS2012起,MSDN声明“默认生成的值是非确定性且加密安全的”,可能是通过Windows的加密服务。
答案 1 :(得分:0)
可以将read
个随机字节直接导入float
(例如float f; read(fd, &f, sizeof(f));
);假设IEEE-754,所有比特模式都是有效的(尽管存在两个无穷大且许多安静和信令NaN)。您可以使用ieee754.h
或fpclassify.h
来确定您是否击中了其中一个。
当然,这是否合理取决于您想要的分发类型。假设IEEE-754 float32
,您将在[0,2 -126 )非正规数和[2 -126 的每个范围内获得均匀分布。 ,2 -125 ),[2 -125 ,2 -124 ),...,[2 127 ,2 128 )法线(及其否定)。
答案 2 :(得分: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