在C语言中生成从-n到n的随机数

5

我想生成从-n到n之间(不包括0)的随机数。有人能提供C语言代码吗?如何排除0?


1
为什么要点踩?我希望这个网站强制要求人们在点踩时添加评论。 - Ian Roke
3个回答

9

一个想法是在范围[1,2n]内生成一个随机数x。然后对于大于nx,返回-(x-n),否则只返回x

这个方法应该可以工作:

int my_random(int n)
{
  const int x = 1 + rand() / (RAND_MAX / (2 * n) + 1);

  return x > n ? -(x - n) : x;
}

请参阅comp.lang.c FAQ以获取有关如何安全使用rand()的更多信息;它解释了上述用法。


谢谢。Chris刚在你之前发布了答案,所以我这样做了。 - avd

3

我建议的最简单的方法是生成0到2n之间的随机数,然后使用以下数学技巧:

result= n - randomNumber 

尽管出现0的概率很小,但可以使用“if”语句进行检查,并重新生成随机数。

1
int random(int N) 
{ 
  int x;
  do{
    x=rand()%(N*2+1)-N;
  }while(x==0);
  return x;
}

它从-N到N选择一个数字,但如果选择0,则会一直重复此过程。
另一种方法是根据评论中的建议,在- N和N-1之间生成一个数字,并在其为正数或0时将其增加:
int random(int N) 
{ 
  int x;      
  x=rand()%(N*2)-N;
  if(x>=0) x++;
  return x;
}

1
一个依赖于随机值的do-while循环可能会执行很长时间!但是,通过将随机结果的范围减少1,然后人为地将任何0结果转换为缺失的边界结果,您可以摆脱非确定性执行时间。不需要循环。 - Casey Barker
我不同意你的说法,认为这需要“很长很长的时间”:当x为0时(因此循环重复),其概率为1/(2N+1),对于大的N值来说,这是相当小的。 尽管如此,我已经将你的建议纳入我的答案中,我认为这对于这个特定的问题会得出更好的解决方案,所以谢谢 :) - Wernsey
啊...我并没有说它“会”花很长时间,而是说它“可能”需要很长时间。这是有区别的! :)如果听起来有点傲慢,我向您道歉。我在实时软件领域工作,在那里任何无法绝对保证在某个确定时间内完成的事情“可能需要很长时间”。从技术上讲,您的第一个版本是O(?),而您的第二个版本是O(1)(或者最坏情况下不比“rand”复杂)。因此,就确定性而言,您的第二个版本是一个很大的改进。顺便说一句,做得好。我的“将0转换为边界”的建议不会像这样漂亮。 - Casey Barker

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