C 是否可以使用math.h的rand()生成随机浮点数(包括次正常值)?

C 是否可以使用math.h的rand()生成随机浮点数(包括次正常值)?,c,random,c99,C,Random,C99,我想生成包含次正常浮点数的浮点数。我们可以使用math.h的例程rand()来实现这一点吗?编程语言应该是C99。我希望这个随机数从[-1e308到1e308]均匀分布 union { int a; float b; } Number; Number.a = rand(); printf("%f\n", Number.b); 这将使用随机整数的位掩码创建具有相同位掩码的浮点数。写入联合的一个字段并从另一个字段读取通常会遇到问题,但以下操作在许多系统上都很有效: 这将生成非a编号 do

我想生成包含次正常浮点数的浮点数。我们可以使用
math.h的例程
rand()
来实现这一点吗?编程语言应该是
C99
。我希望这个随机数从[-1e308到1e308]均匀分布

union {
  int a;
  float b;
} Number;

Number.a = rand();
printf("%f\n", Number.b);

这将使用随机整数的位掩码创建具有相同位掩码的浮点数。

写入联合的一个字段并从另一个字段读取通常会遇到问题,但以下操作在许多系统上都很有效:

这将生成非a编号

double随机\u double(无效){
联合{
无符号字符uc[sizeof(double)];
双d;
}u;
未签名的i;

对于(i=0;i来说,这不是很有效,但要正确回答这个问题:


首先定义一个从整数范围(0,MAX_RAND)到实数的映射。在定义此映射时,请准确确定所需的分布:所有实数上的一致分布,或对数一致分布,或其他任何分布。编写一个函数,在该范围内给定一个整数,根据此映射返回一个double。现在使用RAND()请注意,使用
rand
这将始终是伪随机数,而不是真正的随机数。使用
rand
生成符号、分数和指数部分,并将它们重新组合为
float
。请参见@rospresser glibc的哪一部分?@rospresser,这样做不会得到非标准化结果。这似乎是合理的e回答。但是有人投了反对票。为什么?我还不是反对票,但严格来说,这个程序的行为是未定义的。@Bathsheba你能解释为什么吗?如果
sizeof(int)==sizeof(float),在c99中是正确的
。如果一个联合中的一个成员自c99以来占用相同的字节,则可以写入该成员,而从另一个成员读取。@mch,因为一个成员可以具有陷阱表示。使用这种方法生成的随机数的分布是什么?
double random_double(void) {
  union {
    unsigned char uc[sizeof (double)];
    double d;
  } u;
  unsigned i;
  for (i=0; i<sizeof u.uc; i++) {
    u.uc[i] = rand();
  }
  return u.d;
}
double rand_double_NotNAN(void) {
  union {
    double d;
    unsigned char uc[sizeof(double)];
  } u;
  do {
    for (size_t i = 0; i < sizeof(double); i++) {
      u.uc[i] = rand();
    }
  } while (isnan(u.d));
  return u.d;
}