C语言 在C中生成范围内的随机整数值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15962102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:01:23  来源:igfitidea点击:

Generating random integer values within a range in C

crandomnumbersintegergenerator

提问by Kane Charles

How do I go about generating random integer values between a range (in this case 1-12 including 1 and 12) in the C language?

如何在 C 语言中生成范围(在本例中为 1-12,包括 1 和 12)之间的随机整数值?

I've read about seeding (srand()) and using rand() within a range but am unsure about how to go about it.

我已经阅读了有关播种 (srand()) 和在一定范围内使用 rand() 的内容,但不确定如何进行。

Edit: Here is what I have so far

编辑:这是我到目前为止

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

// Craps Program
// Written by Kane Charles
// Lab 2 - Task 2

// 7 or 11 indicates instant win
// 2, 3 or 12 indicates instant los
// 4, 5, 6, 8, 9, 10 on first roll becomes "the point"
// keep rolling dice until either 7 or "the point is rolled"
//      if "the point" is rolled the player wins
//      if 7 is rolled then the player loses

int wins = 0, losses = 0;
int r, i;
int N = 1, M = 12;
int randomgenerator();


main(void){

  /* initialize random seed: */
  srand (time(NULL));
  /* generate random number 10,000 times: */
  for(i=0; i < 10000 ; i++){
     int r = randomgenerator();
     if (r = 7 || 11) {
        wins++;
     }
     else if (r = 2 || 3 || 12) {
        losses++;
     }
     else if (r = 4 || 5 || 6 || 8 || 9 || 10) {
        int point = r;
        int temproll;
        do
        {
            int temproll = randomgenerator();

        }while (temproll != 7 || point);

        if (temproll = 7) {
            losses++;
        }
        else if (temproll = point) {
            wins++;
        }
     }
  }
    printf("Wins\n");
    printf("%lf",&wins);
    printf("\nLosses\n");
    printf("%lf",&losses);
}

int randomgenerator(){
    r = M + rand() / (RAND_MAX / (N - M + 1) + 1);
    return r;
}

回答by Matt Phillips

The simple way is

简单的方法是

#include <stdlib.h>
#include <sys/time.h>

int main(void)
{
    struct timeval t1;
    gettimeofday(&t1, NULL);
    srand(t1.tv_usec * t1.tv_sec);

    int a = 1, b = 12;

    int val = a + (b-a) * (double)rand() / (double)RAND_MAX + 0.5;

    return 0;
}

Edit, since someone asked: You really do have to use floating point arithmetic to get this to come out right (or as right as it can given rand()'s limitations such as they are). Any solution which relies purely on integer arithmetic and rand()will of necessity use \or %, and when this happens you will get roundoff error--where c and d are declared intand c = 5 and d = 2, for example, c/d == 2 and d/c == 0. When comes to sampling from a range, what happens is that in compressing the range [0, RAND_MAX]to [a, b], you have to do some kind of division operation since the former is so much larger than the latter. Then roundoff creates bias (unless you get really lucky and things evenly divide). Not a truly thorough explanation but I hope that conveys the idea.

编辑,因为有人问:你真的必须使用浮点运算才能得到正确的结果(或者尽可能正确,rand()例如它们的限制)。任何完全依赖于整数算术并且rand()必须使用\or 的解决方案,%当发生这种情况时,您将得到舍入错误——其中声明了 c 和 dint并且 c = 5 和 d = 2,例如,c/d == 2和 d/c == 0。当从范围中采样时,发生的情况是在将范围压缩[0, RAND_MAX]到 时[a, b],您必须进行某种除法运算,因为前者比后者大得多。然后四舍五入会产生偏差(除非你真的很幸运并且事情平分秋色)。不是一个真正彻底的解释,但我希望能传达这个想法。

回答by Grijesh Chauhan

You should use: M + rand() / (RAND_MAX / (N - M + 1) + 1)

您应该使用:M + rand() / (RAND_MAX / (N - M + 1) + 1)

Don't use rand() % N(which tries to return numbers from 0 to N-1). It is poor, because the low-order bits of many random number generators are distressingly non-random. (See question 13.18.)

不要使用rand() % N(它试图返回从 0 到 N-1 的数字)。它很糟糕,因为许多随机数生成器的低阶位令人痛苦地是非随机​​的。(见问题 13.18。

Example code:

示例代码:

#include <stdio.h>      /* printf, scanf, puts, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */
int main ()
{
  int r, i;
  int M = 1,
      N = 12;
  /* initialize random seed: */
  srand (time(NULL));

  /* generate number between 1 and 12: */
  for(i=0; i < 10 ; i++){ 
     r = M + rand() / (RAND_MAX / (N - M + 1) + 1);
     printf("\n%d", r);
  }
  printf("\n") ;
  return EXIT_SUCCESS;
}

It's working here at codepad.

它在codepad上工作。