如何从中获取随机浮点值/dev/urandom
?
如果我只是使用演员表,请说:
int fd = ::open("/dev/urandom", O_RDONLY);
uint32_t n;
read(fd, &n, sizeof(n));
float f = n;
...我不确定我是否有可移植性的保证,因为我不知道大的值n
是否一定可以表示为f
?MAXUINT 是否保证可以表示为float
?
如何从中获取随机浮点值/dev/urandom
?
如果我只是使用演员表,请说:
int fd = ::open("/dev/urandom", O_RDONLY);
uint32_t n;
read(fd, &n, sizeof(n));
float f = n;
...我不确定我是否有可移植性的保证,因为我不知道大的值n
是否一定可以表示为f
?MAXUINT 是否保证可以表示为float
?
您从 /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。
可以将read
随机字节直接放入一个float
(例如float f; read(fd, &f, sizeof(f));
);假设 IEEE-754,所有位模式都是有效的(尽管有两个无穷大和许多安静和信令 NaN)。您可以使用ieee754.h
orfpclassify.h
来确定您是否击中了其中之一。
当然,这是否合理取决于你想要什么样的分布。假设 IEEE-754 ,您将在 [0, 2 -126 ) 非正规和 [2 -126 , 2 -125 ), [2 -125 , 2 -124 ), ...float32
的每个范围内得到均匀分布。 , [2 127 , 2 128 ) 法线(及其否定)。
您可以通过将随机整数除以最大整数值来获得随机数浮点数。
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