rand() 和 srand() 给出了奇怪的相似结果.rand() 的返回非常相似 [英] rand() with srand() is giving strangely similar results. The return from rand() is very similar

查看:62
本文介绍了rand() 和 srand() 给出了奇怪的相似结果.rand() 的返回非常相似的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个看似常见的问题,所以我希望我不会听起来多余.但是 rand() 返回的范围应该在 0 到 RAND_MAX 之间,但是,当我执行一个非常简单的 rand 语句时,我总是得到一个很小范围内的返回值.

This is a seemingly common question, so I hope I don't sound redundant. But the range returned from rand() should be between 0 and RAND_MAX, however, when I do a very simple rand statement, I'm always getting returns within a very small range.

这个范围类似于 1,4XX,XXX,XXX.我想这可能是时钟问题,所以我等了三十分钟,但我仍然得到相同范围内的数字.

This range is something like 1,4XX,XXX,XXX. I figured this might be a clock thing, so I waited thirty minutes and I'm still getting numbers in the same range.

这是 20 分钟前的一些示例输出:

Here is some sample output from twenty minutes ago:

Matthews-Macbook-Pro:Data_Structures matthewwright$ ./main
1439810968
80
Matthews-Macbook-Pro:Data_Structures matthewwright$ ./main
1439827775
29
Matthews-Macbook-Pro:Data_Structures matthewwright$ ./main
1439827775
29
Matthews-Macbook-Pro:Data_Structures matthewwright$ ./main
1439844582
78
Matthews-Macbook-Pro:Data_Structures matthewwright$ ./main
1439878196
29
Matthews-Macbook-Pro:Data_Structures matthewwright$ ./main
1439895003
78

这是刚才的示例输出:

Matthews-Macbook-Pro:Data_Structures matthewwright$ ./main
1456483512
78
Matthews-Macbook-Pro:Data_Structures matthewwright$ ./main
1456500319
80
Matthews-Macbook-Pro:Data_Structures matthewwright$ ./main
1456500319
80
Matthews-Macbook-Pro:Data_Structures matthewwright$ ./main
1456517126
29
Matthews-Macbook-Pro:Data_Structures matthewwright$ ./main
1456533933
78

我知道 rand() 并不完美,但这似乎太相似了,不正确.如果范围是 0 - RAND_MAX,那么返回的每个数字都在同一范围内似乎很奇怪.

I know rand() isn't perfect, but this seems too similar to be correct. If the range is 0 - RAND_MAX, it seems weird that every number returned is in the same range.

这是我正在测试的代码:

Here is the code I was testing:

#include <iostream>
#include <stdio.h>      /* printf, scanf, puts, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */

int main(int argc, char const *argv[])
{
    /* declarations */
    srand(time(NULL));

    std::cout << std::rand() << std::endl;
    std::cout << std::rand()%100 << std::endl;
    return 0;
}

我不认为我需要所有这些#include 语句,但我看到其他人使用它们,所以我将它们包括在内,以防它会影响我的输出,但它没有.

I don't think I needed all those #include statements, but I saw other people using them so I included them just in case it would affect my output, but it didn't.

所以@Mgetz 和@Curious 提供的链接非常有用.为了整合,

So the links provided by @Mgetz and @Curious were super helpful. To consolidate,

信息页面:http://en.cppreference.com/w/cpp/数字/随机/uniform_int_distribution

超级有用的讲座(真实的,观看这个):https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful

Super helpful lecture (for real, watch this): https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful

我在自己的笔记中总结了我在讲座中听到的内容,这样我就不会忘记了下次重新研究.我没有在这里写代码,大部分代码都在上面链接的信息页面"中.大多数评论都包含讲座中的信息,尽管它不是讲座中的逐字逐句.再次,我真的建议看那个.信息量大,信息量大.

I summarized what I heard in the lecture on my own notes, just so I won't have to re-research this another time if I forget. I didn't write the code here, most of the code is within on that "Info page" linked above. Most of the comments contain information from the lecture, though it isn't verbatim from the lecture. Again, I really recommend watching that. It is dense with good information.

#include <iostream>
#include <random>

int main(int argc, char const *argv[])
{
    /* https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful */

    /* Randomness Verson 1 : Deterministic */
    std::mt19937 mt(1234);
    std::uniform_int_distribution<int> dist(0,127);
    /* Default is int, but we could specify others.
     * The range is [inclusive, inclusive]
     * 
     * Above is Mersenne Twister RNG. It is deterministic, meaning we can get the same result
     * if we use "std::mt19937 mt(1234)"; or something like that. This could be useful for some
     * people (He mentions games, some experiments, et cetera). It is stupid fast.
     * 
     * However, it isn't cryptographically secure, but it pretty random as random goes. If you
     * track the output though, you could guess the next numbers, so don't use it for anything
     * secure.
     */

    /* Randomness Verson 2 */
    std::random_device rd;  //Will be used to obtain a seed for the random number engine
    std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
    std::uniform_int_distribution<int> dis(0, 127); // Inclusive
    /* This is not reproducible. This is not deterministic.
     * "Possibly Crypto-secure." Seems like using Random Device makes this near perfect random,
     * assuming some conditions. I'm not a man who's written security software, and if you are 
     * writing security software, I assume you're not looking at StackOverflow to figure out how
     * to do random numbers. The way he talked about it in the lecture made this seem much more 
     * secure, but I'm not sure what I'm talking about when it comes to these things
     */

    for (int i = 0; i < 3; ++i)
    {
        /* Below would output the pure Mersenne Twister output, deterministic. This seems to
         * be pretty random, but it isn't totally random. */
        std::cout << dist(mt) << " ";

        /* And below would output the random device output. This should be slower, but
         * more truly random. */

        //Use dis to transform the random unsigned int generated by gen into an int in [1, 6]
        std::cout << dis(gen) << " ";

        std::cout<< std::endl;
    }
}

推荐答案

使用模数运算符会在结果随机数"中带来一定程度的偏差.此外,rand() 函数的工作是实现定义的,不遵循跨平台的标准算法.

Using the modulus operator brings in some amount of bias in the resulting "random number". Further the working of the rand() function is implementation defined and does not follow a standard algorithm across platforms.

考虑使用更现代的 C++11 随机数生成功能,这些功能使用标准的广泛接受的随机数生成算法,跨平台工作相同(当然,给定相同的种子).

Consider using more modern C++11 random number generation features that use standard widely accepted random number generation algorithms, that work the same across platforms (given the same seed of course).

请参阅 cppreference 页面的 std::uniform_int_distribution 示例

#include <random>
#include <iostream>

int main()
{
    std::random_device rd;  //Will be used to obtain a seed for the random number engine
    std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
    std::uniform_int_distribution<> dis(1, 6);

    for (int n=0; n<10; ++n)
        //Use dis to transform the random unsigned int generated by gen into an int in [1, 6]
        std::cout << dis(gen) << ' ';
    std::cout << '\n';
}

<小时>

这里是 Stephan Levavej 精彩演讲的链接,更深入地探讨了这一点https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful

这篇关于rand() 和 srand() 给出了奇怪的相似结果.rand() 的返回非常相似的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆