【问题标题】:Accurately finding the range of numbers generated?准确找到生成的数字范围?
【发布时间】:2017-11-28 15:38:24
【问题描述】:

我很可能把整个代码都做错了,但是在尝试查找范围时:

4.0*rand()/RAND_MAX + 1

我最终只得到了数字 0,而且我很确定还有更多。

代码(C 语言):

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


int main()
{
srand(time(NULL));

 int r;
 4.0*rand()/RAND_MAX+1;
 printf("%i",r);

return 0;
}

【问题讨论】:

  • 找到一个范围?单数?嗯?
  • r 未分配任何值。变量r 包含垃圾。
  • rand()/RAND_MAX 导致分布不均。 数学上代码需要做rand()/(RAND_MAX + 1)。建议4.0*rand()/(RAND_MAX+1.0)+1; 更好的代码可以更准确地处理RAND_MAXdouble,就像4.0*rand()/(RAND_MAX+ 1LLU)+1; 一样

标签: c range


【解决方案1】:

double rr = 4.0*rand()/RAND_MAX+1; 您需要使用双精度,更重要的是,将结果 (rr) 分配给某个变量。

printf("%lf",rr); 用于打印结果。

据了解,这里没有范围计算。

您只是在打印一个未初始化的变量 (r)。 (打印时似乎包含值0)。

【讨论】:

  • .0 之后的4 之外的所有内容都表明其意图是整数数学。不用说,与使用整数相比,使用双精度数会给出非常不同的分布;更不用说在使用双打时尝试对实际分布进行实际核算的困难,您明智地不要尝试。
  • @Patrick87.: 请不要介意,但你能澄清一下吗?这里的分布会有所不同,范围将是无限的,但如果我们这样认为,无论现在的数字是多少,我们都会考虑双精度的整数部分,那么是的,这是可行的。如果我错了,或者纠正我?
  • 没问题 - 分布将是具有RAND_MAX+1 可能结果的离散分布。由于截断,间距会有点不均匀,但如果 R​​AND_MAX 是 32 位整数并且我们正在谈论双精度数,则重复和降低间距不应该有问题。在相同的假设下,使用此公式并保留整数部分将产生与纯整数代码完全相同的分布。
  • @Patrick87.:我不知道为什么 OP 会问这样的问题。我的意思是也许是OP自己的一些实验。否则我不知道。我只是专注于那部分,是的,存在分配问题,如果正在完成,则不会由于 int 算术而截断。感谢您的光临和解释。
【解决方案2】:

两件事:

首先,您永远不会为 r 分配任何值。你需要把4.0*rand()/RAND_MAX+1;改成r = 4.0*rand()/RAND_MAX+1;

其次,编译器可能会抱怨这一点,因为您正在从 double 降级为 int。您应该将4.0 更改为4

最终代码应该大致类似于r = 4*rand()/RAND_MAX+1;。然后,范围将是 {1, 2, 3, 4, 5}(注意:取决于 rand 是否可以返回 RAND_MAX 或仅小于 RAND_MAX。如果仅小于,则排除 5。)如果您想要 {0, 1, 2, 3} 您需要将 RAND_MAX+1 括在括号中。

注意:正如 cmets 中所指出的,上述内容可能存在一些问题。你可以使用这样的东西来获得完全相同的分布:

r = rand()
if (r == RAND_MAX) return 5;
else return r % 4 + 1;

如果您不想返回 5,可以使用拒绝抽样:

r = RAND_MAX;
while (r == RAND_MAX) r = rand();
return r % 4 + 1;

【讨论】:

  • 但是rand()/RAND_MAX 不是0 吗?这是积分数学。
  • @coderredoc 是(如果rand 不能返回RAND_MAX,我不记得了,但我会同意)但是4*rand()/RAND_MAX 可以返回非零数字,因为4*rand() 应该是首先评估。
  • 4 * rand() 如果 RAND_MAX 为 INT_MAX,可能会溢出
  • @Bob__ 公平点; RAND_MAX 的值取决于实现。这将需要检查。在我的环境中看起来是 32,767(最低保证值),所以没问题。
  • rand() 可以返回RAND_MAX
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-19
  • 1970-01-01
  • 2017-03-23
  • 1970-01-01
  • 2020-10-24
  • 2021-12-10
  • 2020-06-26
相关资源
最近更新 更多