如何在C语言中生成随机double数?

3

我需要通过一种自动生成繁琐的输入测试数据的方法来引入实验数据到我的代码中。考虑到我还必须考虑双精度double类型的数量,我该如何做呢?

这里有一些额外的背景信息。从这本书的第139页 http://mimoza.marmara.edu.tr/~msakalli/cse706_12/SkienaTheAlgorithmDesignManual.pdf(准确地说是PDF的第151页),我需要解决问题4.3,这个问题我已经解决了。然而,我需要为这个问题生成随机输入,由于我必须处理实数,可能需要生成double数字。问题是我不知道在生成实数时应选择什么范围。


2
你想要哪个范围的双精度浮点数? - dbush
1
也许可以查看 man drand48 https://linux.die.net/man/3/drand48 - Bodo
你想要所有的 double,还是一个子范围,比如 [0...1)? - chux - Reinstate Monica
2
@Neri-kun 如果你只需要一个double,可以使用42.0。但是,如果你需要从一组double中随机选择一个,那么这个组合应该包括哪些值呢? - chux - Reinstate Monica
1
@chux 那么,作为入门,我会选择一个范围在-DBL_MAXDBL_MAX之间的区间,仅供实验之用。 - Neri-kun
显示剩余8条评论
4个回答

5
为了实现一个随机的 double,其取值范围在 [-DBL_MAX ....DBL_MAX] 之间且每个 double 的出现机会大致相等,需要随机地生成一个 double。但要拒绝非有限值。
#include <math.h>
#include <stdlib.h>

double rand_finite_double(void) {
  union {
    double d;
    unsigned char uc[sizeof(double)];
  } u;
  do {
    for (unsigned i = 0; i < sizeof u.uc; i++) {
      u.uc[i] = (unsigned char) rand();
    }
  } while (!isfinite(u.d));
  return u.d;
}

每次循环通常只生成8位,因此效率相对较低。


我尝试打印您的函数调用,但每次运行代码时它都返回 -0.000000。我有没有做错什么?另外,为什么您使用了一个 union?是为了通过将 uc[] 赋予随机数更有效地修改 u.d 吗? - Neri-kun
1
@Neri-kun 如果你使用 %f 打印,它只会打印整数部分加上小数点后六位数字。如果值在 -0.000001 和 0.000001 之间,它将显示为 0.0。尝试使用 %e 进行打印,它使用科学计数法。 - dbush
@Neri-kun "还有,你为什么使用了union?" --> 简单来说,这是最好的方法。"更有效率" --> 相对于什么?如建议,使用'%e"进行打印。 - chux - Reinstate Monica

4

C语言的rand()函数返回一个整数,通常为32位。双精度浮点数有53位的尾数。因此,为了创建一个好的随机双精度浮点数,您需要生成53个随机位。可以尝试以下代码:

double rd() {
    uint64_t r53 = ((uint64_t)(rand()) << 21) ^ (rand() >> 2);
    return (double)r53 / 9007199254740991.0; // 2^53 - 1
}

这将返回一个在区间[0,1]中的双精度数值


真的,但他想要使用标准库快速简便的方法。当然,一个附加库会更好(比如我的ojrandlib :-))。此外,我对它进行了微调,以避免rand()的低位比特,这通常是问题所在。 - Lee Daniel Crocker
@LeeDanielCrocker 在这种情况下,您能否提供另一种实现方式,就像P__J__所说的那样,生成一个“好”的随机数? - Neri-kun
有许多适用于C语言的优秀PRNG库。我在Github上发布的ojrandlib只是其中之一(但对于您简单的需求来说可能过于复杂)。 - Lee Daniel Crocker

1
例如,从0到max:
double pseudorand(double max)
{   
    srand((unsigned) time(0));
    return (max / RAND_MAX) * rand();
}

或者从 -max 到 max。
double pseudorand(double max)
{   
    srand((unsigned) time(0));
    return (rand() > RAND_MAX / 2 ? -1 : 1) *(max / RAND_MAX) * rand();
}

https://onlinegdb.com/SyqGH9PqN


0

如何在C语言中生成随机双精度数?

没有花里胡哨的东西,但可以让你开始:

double drand ( double low, double high )
{
    srand((unsigned int)clock());
     return ( (double)rand() * ( high - low ) ) / (double)RAND_MAX + low;
}

对于 low = 10.0;high = 1000.0,调用此函数将生成一个值:10 >= value <= 1000.0
改编自this example

问题在于低位和高位是否足够大,以生成“inf”值。 - 0___________
@P__J__ - 不,它不是完美的,而且可以做更多的事情,但它回答了问题。我觉得有趣的是你这么快就找到了这个(和其他)帖子的问题,而没有先仔细检查自己的帖子。例如,如果您的任何一个函数被快速连续调用会发生什么?(提示. ) - ryyker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接