How to use to replace rand()?

后端 未结 5 809
执笔经年
执笔经年 2020-12-28 13:45

C++11 introduced the header with declarations for random number engines and random distributions. That\'s great - time to replace those uses of <

5条回答
  •  情话喂你
    2020-12-28 14:08

    Abusing the fact that engines return values directly

    All engines defined in has an operator()() that can be used to retrieve the next generated value, as well as advancing the internal state of the engine.

    std::mt19937 rand (seed); // or an engine of your choosing
    
    for (int i = 0; i < 10; ++i) {
      unsigned int x = rand ();
      std::cout << x << std::endl;
    }
    

    It shall however be noted that all engines return a value of some unsigned integral type, meaning that they can potentially overflow a signed integral (which will then lead to undefined-behavior).

    If you are fine with using unsigned values everywhere you retrieve a new value, the above is an easy way to replace usage of std::srand + std::rand.

    Note: Using what has been described above might lead to some values having a higher chance of being returned than others, due to the fact that the result_type of the engine not having a max value that is an even multiple of the highest value that can be stored in the destination type.
    If you have not worried about this in the past — when using something like rand()%low+high — you should not worry about it now.

    Note: You will need to make sure that the std::engine-type::result_type is at least as large as your desired range of values (std::mt19937::result_type is uint_fast32_t).


    If you only need to seed the engine once

    There is no need to first default-construct a std::default_random_engine (which is just a typedef for some engine chosen by the implementation), and later assigning a seed to it; this could be done all at once by using the appropriate constructor of the random-engine.

    std::random-engine-type engine (seed);
    

    If you however need to re-seed the engine, using std::random-engine::seed is the way to do it.


    If all else fails; create a helper-function

    Even if the code you have posted looks slightly complicated, you are only meant to write it once.

    If you find yourself in a situation where you are tempted to just copy+paste what you have written to several places in your code it is recommended, as always when doing copy+pasting; introduce a helper-function.

    Intentionally left blank, see other posts for example implementations.

提交回复
热议问题