zoukankan      html  css  js  c++  java
  • 认识随机函数rand()和srand(unsigned int )

    随机函数rand

    rand函数

    int rand( void );

    该函数是一个无参数函数,返回值是一个int类型的随机数,其值的范围是[0 , 0x7fff]即[0 , 32767]。虽然这个函数不需要参数,但是rand函数运行是需要一个seed(种子),种子由srand()函数提供。这个srand函数我们待会在介绍.rand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。srand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,从而实现真正意义上的“随机”。通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列。

    srand函数

    void srand(unsigned seed);

    srand和rand()配合使用产生伪随机数序列。只要该函数的参数发生变化,rand函数就能产生随机值,如果该函数的参数是一个定值,那么rand函数每次函数的随机数就和上一次产生的值一样.如果我们需要多次调用rand函数,产生不同的随值,我们就需要给他设置不同的seed。

    实例一:

    #include<stdio.h>
    #include<stdlib.h>
    int main()
    {
        int i;
        unsigned int seed;
        int input;
        for(i=0;i<10;i++)
        {
            scanf("%d",&input);
            seed = (unsigned)input;
            srand(seed);
            printf("Random value is %d
    ",rand());
        }
        return 0;
    }
    

    运行上面的程序后,我们又发现,我们不能保证每次输入的seed值绝对与上次不一样。于是我们采用时间来作为seed,因为时间当前时间总是在变化的,或者说时间流逝的距离总是在变化的。我们可以采用当前前时间作为种子。

    实例二:

    #include<stdio.h>
    #include<stdlib.h>
    #include<time.h>
    int main()
    {
        int i;
        time_t t;
        srand((unsigned)time(&t));
        for(i =0; i<10;i++)
        {
            printf("Random value is %d
    ",rand());
        }
        return 0;
    }
    

    产生指定区间内的随机数

    在实际的编程的时候,我们不总是需要[0 , 0x7fff]区间内的所有数,可能我们只需要其中一部分[0 , 15]内的随机数。这是我们就该避免产生大于15的数。我们可以通过对rand()函数的返回值取余数 RandomValue = rand() % (15 + 1) 。一般的,我们要产生[0 , N]的随机数,可以RandomValue = rand() % (N + 1);如果要产生[0 , N)随机数,可以RandomValue = rand() % N 。需求总是越来越多,需要产生[M , N]区间的随机数是怎么办呢?我们可以认为区间[M , N]是由[0 , N - M]向右边位移 M 个单位得到的。我们通过产生[0 , N - M]区间内的随机数加上M得到 [M , N]区间内的随机数,这好似一个巧妙的转换过程。

    实例三:

    /*获取区间[2,99]的随机数
    #include<stdio.h>
    #include<stdlib.h>
    #include<time.h>
    #define M 2
    #define N 99
    int main()
    {
        int i;
        time_t t;
        srand((unsigned)time(&t));
        for(i=0;i<100;i++)
        {
            printf("%d	",M + rand() % (M - N + 1));
        }
        return 0;
    }
    

    产生随机浮点数

    rand /(double)RANDMAX; 可以随机产生[0.0 , 1.0]区间内的小数, rand / (double)(RANDMAX + 1) 可以产生[0.0 , 1.0)区间的小数。结合上面产生任意区间数的方法,我们就可以随机产生任意区间内的浮点数了.(注: 第一次rand()产生[M , N)区间内的整数 x1,第二次rand()产生[0.0 ,1.0]的浮点数,最终的到随机在[M , N]区间内的浮点数 FloatValue = x1 + x2).

    实例四:

    #include<stdio.h>
    #include<stdli.h>
    #include<time.h>
    int Sentinel = 0;//设置哨兵,保证只设置一次种子
    double RandomFloate(int M, int N)
    {
    int RandomValue1;
    double RandomValue2;
    if(Sentinel == 0)
    {
    time_t t;
    srand((unsigned)time(&t));
    }
    RandomValue1 = M + rand() % (M - N + 1);
    RandomValue2 = rand() / (double)(RAND_MAX + 1);
    return RandValue + RandomValue2;
    }
    int main()
    {
        int i;
        for(i= 0;i<100; i++)
            {
                printf("%f	",RandomFloate(2,5));
            }
    }
    

    rand函数误区

    rand()函数设置一次种子就可以多次使用。不要将srand((unsigned)time(&t))和rand()这样的组合放在一个循环中,因为在time()函数的单位是秒,可能你的程序在一秒内就运行了 n 次,那么这n次设置的种子就一样的,产生的随机数也是一样的。还需要注意的就是你没有调用srand()函数时候,系统默认你调用了srand(1).

  • 相关阅读:
    ElasticSearch工作原理
    prometheus监控es集群
    es索引调优
    ES中Refresh和Flush的区别
    网络服务器技术Apache与Nginx,IIS的不同
    shell里/dev/fd与/proc/self/fd的区别
    常用抓包工具
    Ubuntu Kubuntu Xubuntu Lubuntu Dubuntu Mythbuntu UbuntuBudgie区别
    Android的Looper.loop()消息循环机制
    申请读写sd卡权限shell
  • 原文地址:https://www.cnblogs.com/shuimojun/p/3804271.html
Copyright © 2011-2022 走看看