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

Is it possible to generate random floating point numbers including subnormals, with rand() of math.h?

我想生成包含次正规浮点数的浮点数。能不能用math.h的套路rand()来实现呢?编程语言应该是C99。我想让这个随机数从[-1e308到1e308]均匀分布。

union {
  int a;
  float b;
} Number;

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

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

写入联合的一个字段并从另一个字段读取通常会遇到麻烦,但以下内容在许多系统上工作得很好:

这将生成非数字。 NAN

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;
}

一种不return NAN 的方法。另见 IEEE 754 specifies an isNaN() predicate which does not raise an exception even when used with signaling NaN

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;
}

效率不高,但要正确回答问题:

首先定义一个从整数范围(0,MAX_RAND)到实数的映射。在定义此映射时,请准确确定您想要的分布:所有实数均匀分布,或对数均匀分布,或其他任何分布。编写一个函数,根据此映射给出 returns 范围内的整数。现在使用 rand() 并将其输入到您的函数中。