zoukankan      html  css  js  c++  java
  • C/C++中随机数的获取: 伪随机函数

    1. C库中的伪随机函数rand的实现

    《The GNU C Library》里说的,大概如下:

    公式: Y=(a*X+c)mod m

    其中,a,c,m都是常数

    一种取值是:

    a = 0x5DEECE66D = 25214903917

    c = 0xb = 11

        m = 2^48

    用上面的公式可以这样写:

    __int64 rand ()
    {
    static __int64 r = 0;
    const __int64 a = 25214903917;
    const __int64 c = 11;
    const __int64 m = 1 << 48;
    r = (r * a + c) % m;
    return r;
    }

    2. ASNI 随机数生成的理解
    ANSI中和随机数生成相关的函数是rand()和srand()。
    rand()函数的原理:y=(a*x+b)mod n
    ANSI通过记录最近生成的数来产生伪随机数。每次调用rand时,它取最近生成的一个数,对这个数执行一系列的操作,产生下一个数。
    所以,在程序中如果多次调用rand的话,会生成不同的随机数。
    但是,如果你多次运行同一个程序的话,产生的随机数序列是一样的,为什么会这样呢?主要是rand在设计的时候需要一个种子,这个种子作为整个随机数过程的起始值。开始运行程序时这个值是库里给定的,所以每次运行程序产生的随机数序列是一样的。
    如果想产生不同的序列的话,就需要改变初始种子。使用srand函数用来设定种子。
    可以利用每次运行程序时的时间来作为种子。这样就会产生不同的序列。

    3. 随机数计算的相关

    关于time_t time(0)
        time_t 被定义为长整型,它将返回从1970年1月1日零时零分零秒到现在所经历过的时间,单位为秒。比如输出 cout<<time(0) ,将得到值约为1169174701,约等于37(年)* 365(天)* 24(小时)* 3600(秒)(月和日不计)。
    关于ran_num=rand()%6
        将rand()的返回值与6求模是必须的,这样才能确保目的随机数落在[0,6)之间,否则很可能会得到一个非常巨大的数值 (RAND_MAX一般为32767)。一个通用的公式是:要想取得[a,b)之间的随机整数,使用(rand()%(b-a))+ a,结果包含 a 而不含 b 。

    4.随机函数 rand,srand,random,srandom 的区别与使用
    使用方法 :
    假如你想产生 1-10 之间的一个随机数, 你应该像下面这样编码

      j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));

     而不是下面这样的代码

       j = 1 + (rand() % 10);


    结论:如果你使用 srandom 种植种子, 则你应该使用 random 返回随机数, 如果你使用 srand 种植种子, 则你应该使用rand返回随机数。
    不过srand和rand官方已经不推荐使用。原因是产生随机数的性能不是很好, 另外是随机数的随机性没有random好, 再者就是不是线程安全。

  • 相关阅读:
    Leetcode Valid Sudoku
    Leetcode Surrounded Regions
    LeetCode Sqrt
    LeetCode POW
    LeetCode Next Permutation
    ACK-Ackermann, 阿克曼函数
    再不懂时序就 OUT 啦!,DBengine 排名第一时序数据库,阿里云数据库 InfluxDB 正式商业化!
    阿里云提供全托管 ZooKeeper
    性能压测中的SLA,你知道吗?
    第一个入驻阿里云自营心选商城,如今它已经是营收过亿的SaaS独角兽
  • 原文地址:https://www.cnblogs.com/xkfz007/p/2656893.html
Copyright © 2011-2022 走看看