我可以从/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
?
uint32_t
会有什么陷阱表示呢?将其分配给 float
也不会引起问题。此外,假设 /dev/urandom
是均匀的,那么浮点值将是尽可能均匀的,对吧? - Oliver Charlesworth可以直接将随机字节读入到浮点数中(例如:float f; read(fd, &f, sizeof(f));
),假设使用IEEE-754标准,所有位模式都是有效的(尽管有两个无穷大和许多静默NaN和信号NaN)。您可以使用ieee754.h
或fpclassify.h
来确定是否遇到了其中之一。
当然,这是否合理取决于您想要的分布类型。假设使用IEEE-754 float32
,您将获得在每个范围内以及整个范围[0, 2-126)的均匀分布,[2-126, 2-125),[2-125, 2-124),...,[2127, 2128)正常值(以及它们的负值)。
你可以通过将随机整数除以最大整数值来获得一个随机浮点数。
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
RAND_MAX
在 <stdlib.h>
中定义为 int
,而不是像这个答案中的 unsigned int
- 建议另一个宏名称。通常它的值类似于 0x7fffffff
。 - chux - Reinstate Monica
drand48()
这样的接口来生成随机浮点数。 - sarnold/dev/[u]random
,就像你建议的那样,可能比调用rand()
更好,但概念是相同的。)像@sarnold建议的使用drand48()
似乎也是一个不错的解决方案 - 或许更好。 - mpontillodrand48()
的缺点是它使用线性同余算法——适用于科学和大多数游戏,但不适用于密码级别的工作。/dev/urandom
在使用过程中重新填充熵池——但浮点数的格式使我对使用原始位来填充数字的每个字段持怀疑态度... - sarnoldn
的值将在范围 0 .. 4294967295 内均匀分布。将其赋值给f
可能会丢失一些精度,但它仍然应该是相当均匀分布的。是否真的希望在范围 0 .. 4294967295 内使用浮点数值是另一个问题。 - Keith Thompson