V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
speed
V2EX  ›  程序员

关于 C 语言 rand()和 srand()的用法

  •  
  •   speed · 2015-09-14 17:43:26 +08:00 · 3912 次点击
    这是一个创建于 3357 天前的主题,其中的信息可能已经有所发展或是发生改变。
    rand ()生成的是伪随机数,也就是说每次生成的数值都是一样的吗,必须要和 srand ()配合使用, srand ()里的种子是指随机产生几次的意思吗?如何写一个最简洁的随机生成 6 位数,每位取值范围 0-9 的程序啊。
    14 条回复    2015-09-15 10:17:30 +08:00
    sli
        1
    sli  
       2015-09-14 17:50:04 +08:00
    time_t tTime;
    time (&tTime );
    srand ((unsigned int )tTIme );
    int n = rand ()%1000*1000+rand ()%1000;
    sli
        2
    sli  
       2015-09-14 17:51:54 +08:00
    呃,写完想起来貌似不能保证是 6 位数...失误了....
    shuax
        3
    shuax  
       2015-09-14 17:54:18 +08:00   ❤️ 1
    static UINT32 next = 1;

    int __cdecl rand (void )
    {
    next = next * 1103515245 + 12345;
    /* return (unsigned int )(next / 65536 ) % 32768;*/
    return (UINT32 )(next>>16 ) & RAND_MAX;
    }

    void __cdecl srand (unsigned int seed )
    {
    /* And you *should* get a warning if sizes dont match
    */
    next = seed;
    }

    看源代码你就知道为什么有个 srand 了
    speed
        4
    speed  
    OP
       2015-09-14 18:06:03 +08:00
    rand ()%10 表示将产生的随机数对 10 求余,结果为余数,整体表示产生 0 到 9 的随机数。为啥这种方式不可取?
    iamleung
        5
    iamleung  
       2015-09-14 18:06:41 +08:00
    int max = 999999;
    int min = 100000;
    srand ((int )time (0 ));
    int result = rand ()%(max - min + 1 ) + min;
    YUCOAT
        6
    YUCOAT  
       2015-09-14 18:33:01 +08:00
    unsigned RandNumber ()
    {
    srand ((int )time (NULL ));
    unsigned uRet = 0;

    for (int i = 0; i< 6; ++i )
    {
    uRet = uRet * 10 + (rand () % 10 )
    }

    return uRet;
    }
    hitmanx
        7
    hitmanx  
       2015-09-14 18:36:54 +08:00
    @shuax 很清晰,多谢
    jimzhong
        8
    jimzhong  
       2015-09-14 18:49:17 +08:00   ❤️ 1
    不建议用取模的方式获得给定范围的随机数,因为 rand 不能保证取模后分布依然随机。应该先除以 RAND_MAX 映射到[0,1]区间,然后在拉长到你要的区间。
    srand 是给种子,如果 srand 的参数值相同,那么 rand 出来的序列也相同。
    msg7086
        9
    msg7086  
       2015-09-14 21:42:39 +08:00
    @jimzhong 其实也无所谓吧。真需要完全随机数的话也不会去用 RAND () 了。
    billlee
        10
    billlee  
       2015-09-15 00:07:45 +08:00
    @msg7086 rand () 的随机数只是不能用在安全上,还是有很多适合用的地方的。
    imgalaxy
        11
    imgalaxy  
       2015-09-15 00:54:23 +08:00 via Android
    @shuax 难道阁下是幽香作者?好熟悉的 id
    SeaOverflow
        12
    SeaOverflow  
       2015-09-15 09:09:07 +08:00
    3 楼正解, rand ()是根据随机数种子产生随机数,如果随机数种子不变,那么多次运行产生的随机数都是一样的(每次运行都是从 100,200,300 这种顺序结果),即是伪随机。 srand ()是更改随机数种子,以保证 rand ()产生的随机数是真随机,一般使用系统时钟来更改随机数种子。(如有错误请轻喷!)
    w99wen
        13
    w99wen  
       2015-09-15 09:55:01 +08:00
    先说下所谓的随机的意思:
    其实 c/c++里面的随机都是基于一张表。这张表保证每个位置每个数字出现的概率是一样的,也就是一张随机表。

    rand ()函数是每次都从同一个位置开始,节次取值,每个数字出现的概率也是一样的,取到的也是随机的,不过因为每次都是从同一个位置开始,数字出现的顺序都是一样的。这显然不是我们想看到的。这种方式的到的结果,也就是我们说的伪随机,虽然每个数字再每个位置出现的概率是相同的,可是因为表是固定的,我们总是能有办法知道下一个值是多少。

    那么怎么解决这个问题那,那就是每次在那张随机表里取值的时候,在不同的位置开始取值。这个也就是 srand (), srand = seed + rand 的缩写。我们用 srand (n ),从位置 n 取值, n 是可变的, n 一般用 time (0 ),并且应该保证 n 的随机性。这样就能得到一组完全随机的随机数据了。
    kobe1941
        14
    kobe1941  
       2015-09-15 10:17:30 +08:00
    @w99wen 高手

    @shuax 看源码是个好习惯
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2416 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 01:24 · PVG 09:24 · LAX 17:24 · JFK 20:24
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.