在 C 中生成范围 [0, 1] 内的随机双精度数 [英] Generate random double number in range [0, 1] in C

查看:54
本文介绍了在 C 中生成范围 [0, 1] 内的随机双精度数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在 0 和 1 之间生成随机双数.我如何使用 C 来做到这一点?我尝试生成一个 0 到 100 万之间的整数,然后将结果除以 1M,但效果不佳.

I have to generate random double number in between 0 and 1. How can i do this using C? I've tried to generate an integer number between 0 and one million and then divide the result by 1M but it didn't work out well.

推荐答案

生成介于 0 和 1 之间的随机双数

generate random double number in between 0 and 1

需要考虑的一些事项:

包括 1.0??

我期望在 [0, 1) 范围内"的目标;而不是在[0, 1]范围内".包含 1.0 会造成复杂性,因为它会使分布不平衡.让我们假设 [0, 1).

I'd expect a goal of "in range [0, 1)" rather than "in range [0, 1]". That inclusion of 1.0 creates complexities as it unbalances the distribution. Let us assume [0, 1).

rand() 质量

rand() Quality

rand() 具有未指定的质量,其范围 [0...RAND_MAX] 可能不会以小于 2 的幂的 1 结尾.让我们假设 rand() 目前足够好,RAND_MAX 是一个 Mersenne Number(这很常见),便于使用简单的 ^ 加入多个 rand() 调用.

rand() is of unspecified quality and and its range [0...RAND_MAX] might not end 1 less than a power of two. Let us assume rand() is good enough for now and RAND_MAX is a Mersenne Number (which is very common) to facilitate joining multiple rand() calls with a simple ^.

小数字

大约一半的正 double 小于 1.0.他们都应该有机会吗?

About half of all positive double are less than 1.0. Should all of them have a chance?

典型性 DBL_MANT_DIG 是 53,所以:

Typicality DBL_MANT_DIG is 53 and so:

在 [0.5...1.0) 范围内有 252 double 值.
[0.25...0.5) 范围内有 252 double 值.
[0.125...0.25) 范围内有 252 double 值.
...

There are 252 double values in the [0.5...1.0) range.
There are 252 double values in the [0.25...0.5) range.
There are 252 double values in the [0.125...0.25) range.
...

我们是否希望有 50% 的机会来自第一组,25% 来自下一组,12.5% 来自下一组......?

Do we want a 50% chance of a value from the first group, 25% from the next, 12.5% from the next .... ?

或满意:

Form 253 double 值在 [0.0...1.0) 范围内均匀分布吗?

Form 253 double values in the [0.0...1.0) range evenly distributed?

现在让我们实现第二个目标 - 更容易编码.

Let us go for the second goal for now - easier to code.

在[0...253)范围内生成一个整数double,然后除以253.

Generate an whole number double in the range [0...253) and then divide by 253.

RAND_MAX >= 0x7FFF 根据定义,我们至少得到 15 位随机位.

RAND_MAX >= 0x7FFF by definition, so we get at least 15 bits of random bits.

下面是一些说明性的代码,但效率不高,形成了一个double [0.0 ... 1.0).

Below is some illustrative code that, not so efficiently, forms a double [0.0 ... 1.0).

// Illustrative code
double rand_double_01(void) {
  unsigned long long r = 0;
  #define RANDOM_BITS 15
  for (int i = 0; i < DBL_MANT_DIG; i += RANDOM_BITS) {
    r <<= RANDOM_BITS;
    r ^= rand();
  }
  r %= 1uLL << DBL_MANT_DIG;   // Mask off lower 53 bits
  double dr = r; // expected conversion is exact
  // scale [0 ... 1.0)
  dr /= 1uLL << DBL_MANT_DIG;  // expected conversion/quotient exact 
  return double dr; 
}

注意:当DBL_MANT_DIG >= 64(不常见)或FLT_RADIX != 2(非常不常见)时,上述代码可能会失败.

Note: Above code can fail when DBL_MANT_DIG >= 64 (not common) or FLT_RADIX != 2 (very uncommon).

这篇关于在 C 中生成范围 [0, 1] 内的随机双精度数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆