117

I need to generate random numbers within a specified interval, [max;min].

Also, the random numbers should be uniformly distributed over the interval, not located to a particular point.

Currenly I am generating as:

for(int i=0; i<6; i++)
{
    DWORD random = rand()%(max-min+1) + min;
}

From my tests, random numbers are generated around one point only.

Example
min = 3604607;
max = 7654607;

Random numbers generated:

3631594
3609293
3630000
3628441
3636376
3621404

From answers below: OK, RAND_MAX is 32767. I am on C++ Windows platform. Is there any other method to generate random numbers with a uniform distribution?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
anand
  • 11,071
  • 28
  • 101
  • 159
  • 4
    Build a Dice-O-Matic: http://gamesbyemail.com/News/DiceOMatic – Jarett Millard Sep 04 '09 at 14:04
  • 1
    I had no idea that C++'s `rand()` was uniform. Which library are you using? `cstdlib.h`'s `rand()` is NOT uniform: http://www.cplusplus.com/reference/cstdlib/rand/ – Mike Warren Jul 05 '13 at 08:11
  • 3
    No, rand() is uniform (except in some early buggy implementations). what is not uniform is using the modulus '%' operator to restrict the range. See http://stackoverflow.com/questions/2999075/generate-a-random-number-within-range/2999130#2999130 for a proper solution, or if you have 'arc4random_uniform' available then you can use that directly as well. – John Meacham Oct 07 '13 at 04:00
  • @Alien01: Would you consider changing the accepted answer to the one by "Shoe" ("Why rand is a bad idea" etc..)? My answer is really out of date and everytime I get an upvote for it I feel like someone's running down the wrong aisle. – peterchen Jul 26 '16 at 09:59
  • Nice [white paper](https://isocpp.org/files/papers/n3551.pdf) about random in c++11. – Pupsik May 08 '17 at 11:12
  • Related: The corresponding [canonical question for JavaScript](https://stackoverflow.com/questions/1527803/generating-random-whole-numbers-in-javascript-in-a-specific-range). – Peter Mortensen Aug 24 '22 at 13:12

20 Answers20

216

Why rand is a bad idea

Most of the answers you got here make use of the rand function and the modulus operator. That method may not generate numbers uniformly (it depends on the range and the value of RAND_MAX), and is therefore discouraged.

C++11 and generation over a range

With C++11 multiple other options have risen. One of which fits your requirements, for generating a random number in a range, pretty nicely: std::uniform_int_distribution. Here's an example:

#include <iostream>
#include <random>
int main()
{    
    const int range_from  = 0;
    const int range_to    = 1000;
    std::random_device                  rand_dev;
    std::mt19937                        generator(rand_dev());
    std::uniform_int_distribution<int>  distr(range_from, range_to);

    std::cout << distr(generator) << '\n';
}

Try it online on Godbolt

And here's the running example.

Template function may help some:

template<typename T>
T random(T range_from, T range_to) {
    std::random_device                  rand_dev;
    std::mt19937                        generator(rand_dev());
    std::uniform_int_distribution<T>    distr(range_from, range_to);
    return distr(generator);
}

Other random generators

The <random> header offers innumerable other random number generators with different kind of distributions including Bernoulli, Poisson and normal.

How can I shuffle a container?

The standard provides std::shuffle, which can be used as follows:

#include <iostream>
#include <random>
#include <vector>
int main()
{    
    std::vector<int> vec = {4, 8, 15, 16, 23, 42};
 
    std::random_device random_dev;
    std::mt19937       generator(random_dev());
 
    std::shuffle(vec.begin(), vec.end(), generator);
    std::for_each(vec.begin(), vec.end(), [](auto i){std::cout << i << '\n';});
}

Try it online on Godbolt

The algorithm will reorder the elements randomly, with a linear complexity.

Boost.Random

Another alternative, in case you don't have access to a C++11+ compiler, is to use Boost.Random. Its interface is very similar to the C++11 one.

snipsnipsnip
  • 2,268
  • 2
  • 33
  • 34
Shoe
  • 74,840
  • 36
  • 166
  • 272
  • 34
    GIVE ATTENTION to this answer, since it's far more modern. – gsamaras Dec 12 '14 at 21:51
  • *This* is the right answer. Thanks! Still, I'd like to see a more in-depth description of every step of that code. E.g. what is a `mt19937` type? – Apollo Nov 23 '15 at 16:37
  • @Apollo The documentation says "32-bit Mersenne Twister by Matsumoto and Nishimura, 1998". I'm assuming it's an algorithm to generate pseudo-random numbers. – Shoe Nov 23 '15 at 18:14
  • 1
    @Shoe, for a given range, it generates numbers in same order, `1 9 6 2 8 7 1 4 7 7`. Do you how to randomize this every time we run the program? –  Apr 02 '16 at 05:44
  • @gsamaras when the question was first asked in 2008, C++11 and its new random facilities didn't exist yet. This answer is definitely better; relying on the standard library lets you avoid all the common mistakes, like not realizing how the modulo operator skews the distribution. – Mark Ransom May 07 '16 at 13:15
  • I agree @MarkRansom! – gsamaras May 07 '16 at 14:02
  • Seeding the generator with `std::mt19937 generator(rand_dev());` is not a good idea. The generator has 19,968 bits of internal state: you cannot randomize those with the 32 bits returned by `rand_dev()`. – Richard Aug 11 '16 at 15:59
  • 3
    @Richard What's the alternative? – Shoe Aug 21 '16 at 11:03
  • @Shoe: I've copied the code from the section subtitled "C++11 and generation over a range" but my code appears to have thrown an exception. The compiler didn't throw any errors, but when it ran this was thrown: `terminate called after throwing an instance of 'std::runtime_error' what(): random_device::random_device(const std::string&) This application has requested the Runtime to terminate it in an unusual way.` It also returned `0x3`. As far as I know I'm using the GNU-GCC compiler, but I am quite new to C++ and I do not understand what has occured. – Mushroom Man Jul 02 '17 at 00:26
  • I've added a template function to the answer. hope it helps some people. – Behrouz.M Nov 12 '20 at 07:25
64

Warning: Do not use rand() for statistics, simulation, cryptography or anything serious.

It's good enough to make numbers look random for a typical human in a hurry, no more.

See Jefffrey's reply for better options, or this answer for crypto-secure random numbers.


Generally, the high bits show a better distribution than the low bits, so the recommended way to generate random numbers of a range for simple purposes is:

((double) rand() / (RAND_MAX+1)) * (max-min+1) + min

Note: make sure RAND_MAX+1 does not overflow (thanks Demi)!

The division generates a random number in the interval [0, 1); "stretch" this to the required range. Only when max-min+1 gets close to RAND_MAX you need a "BigRand()" function like posted by Mark Ransom.

This also avoids some slicing problems due to the modulo, which can worsen your numbers even more.


The built-in random number generator isn't guaranteed to have a the quality required for statistical simulations. It is OK for numbers to "look random" to a human, but for a serious application, you should take something better - or at least check its properties (uniform distribution is usually good, but values tend to correlate, and the sequence is deterministic). Knuth has an excellent (if hard-to-read) treatise on random number generators, and I recently found LFSR to be excellent and darn simple to implement, given its properties are OK for you.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
peterchen
  • 40,917
  • 20
  • 104
  • 186
  • 5
    BigRand can give better results even when the desired range doesn't exceed RAND_MAX. Consider when RAND_MAX is 32767 and you want 32767 possible values - two of those 32768 random numbers (including zero) are going to map to the same output, and will be twice as likely to occur as the others. Hardly an ideal random property! – Mark Ransom Jul 13 '09 at 19:36
  • @Mark: You are right, good example. Still, if that's a real problem, I'd avoid built-in `rand()` completely, since the standard doesn't have any quality guarantees. – peterchen Jul 13 '09 at 21:58
  • 10
    (RAND_MAX + 1) is a bad idea. This can rollover and give you a negative value. Better to do something like: ((double)RAND_MAX) + 1.0 – Demi Feb 02 '10 at 05:08
  • 5
    @peterchen: I think you misunderstood what demi was saying. She meant this: `( rand() / ((double)RAND_MAX+1)) * (max-min+1) + min` Simply move the conversion to double and avoid the problem. – Mooing Duck Aug 01 '13 at 18:24
  • 3
    Also, this merely changes the distribution from the bottom 32767 values in the range to even evenly distributed 32767 values in the range, and the remaining 4017233 values will never be selected by this algorithm. – Mooing Duck Aug 01 '13 at 18:28
  • 2
    The given answer is off by 1. The correct equation is: ((double) rand() / (RAND_MAX+1.0)) * (max-min) + min The "max-min+1" is used when using % not *. You will see why when you do min=0, max=1. Could peterchen or @peter-mortensen amend it. – davepc Nov 27 '13 at 19:30
  • 1
    rand() / (RAND_MAX+1) generates a number in the range [0, 1). with min=0, max=1, this is stretched to [0,2) - note that it's an open range on the right side. with the float->int truncate (unfortunately not shown in the code given) you have a result 0 or 1. --- Generally, I'm not happy that this answer was accepted, it's not even a good one, and there's much that needs to be said. I know I *should* write a better reply. – peterchen Feb 19 '14 at 13:50
19

I'd like to complement Shoe's and peterchen's excellent answers with a short overview of the state of the art in 2015:

Some good choices

randutils

The randutils library (presentation) is an interesting novelty, offering a simple interface and (declared) robust random capabilities. It has the disadvantages that it adds a dependence on your project and, being new, it has not been extensively tested. Anyway, being free (MIT License) and header-only, I think it's worth a try.

Minimal sample: a die roll

#include <iostream>
#include "randutils.hpp"
int main() {
    randutils::mt19937_rng rng;
    std::cout << rng.uniform(1,6) << "\n";
}

Even if one is not interested in the library, the website provides many interesting articles about the theme of random number generation in general and the C++ library in particular.

Boost.Random

Boost.Random (documentation) is the library which inspired C++11's <random>, with whom it shares much of the interface. While theoretically also being an external dependency, Boost has by now a status of "quasi-standard" library, and its Random module could be regarded as the classical choice for good-quality random number generation. It features two advantages with respect to the C++11 solution:

  • it is more portable, just needing compiler support for C++03
  • its random_device uses system-specific methods to offer seeding of good quality

The only small flaw is that the module offering random_device is not header-only, one has to compile and link boost_random.

Minimal sample: a die roll

#include <iostream>
#include <boost/random.hpp>
#include <boost/nondet_random.hpp>

int main() {
    boost::random::random_device                  rand_dev;
    boost::random::mt19937                        generator(rand_dev());
    boost::random::uniform_int_distribution<>     distr(1, 6);

    std::cout << distr(generator) << '\n';
}

While the minimal sample does its work well, real programs should use a pair of improvements:

  • make mt19937 a thread_local: the generator is quite plump (more than 2 KB) and is better not allocated on the stack
  • seed mt19937 with more than one integer: the Mersenne Twister has a big state and can take benefit of more entropy during initialization

Some not-so-good choices

The C++11 library

While being the most idiomatic solution, the <random> library does not offer much in exchange for the complexity of its interface even for the basic needs. The flaw is in std::random_device: the Standard does not mandate any minimal quality for its output (as long as entropy() returns 0) and, as of 2015, MinGW (not the most used compiler, but hardly an esoteric choice) will always print 4 on the minimal sample.

Minimal sample: a die roll

#include <iostream>
#include <random>

int main() {
    std::random_device                  rand_dev;
    std::mt19937                        generator(rand_dev());
    std::uniform_int_distribution<int>  distr(1, 6);

    std::cout << distr(generator) << '\n';
}

If the implementation is not rotten, this solution should be equivalent to the Boost one, and the same suggestions apply.

Godot's solution

Minimal sample: a die roll

#include <iostream>
#include <random>

int main() {
    std::cout << std::randint(1,6);
}

This is a simple, effective and neat solution. The only defect is it will take a while to compile – about two years, providing C++17 is released on time and the experimental randint function is approved into the new Standard. Maybe by that time also the guarantees on the seeding quality will improve.

The worse-is-better solution

Minimal sample: a die roll

#include <cstdlib>
#include <ctime>
#include <iostream>

int main() {
    std::srand(std::time(nullptr));
    std::cout << (std::rand() % 6 + 1);
}

The old C solution is considered harmful, and for good reasons (see the other answers here or this detailed analysis). Still, it has its advantages: is is simple, portable, fast and honest, in the sense it is known that the random numbers one gets are hardly decent, and therefore one is not tempted to use them for serious purposes.

The accounting troll solution

Minimal sample: a die roll

#include <iostream>

int main() {
    std::cout << 9;   // http://dilbert.com/strip/2001-10-25
}

While 9 is a somewhat unusual outcome for a regular die roll, one has to admire the excellent combination of good qualities in this solution, which manages to be the fastest, simplest, most cache-friendly and most portable one. By substituting 9 with 4, one gets a perfect generator for any kind of Dungeons & Dragons die, while still avoiding the symbol-laden values 1, 2 and 3. The only small flaw is that, because of the bad temper of Dilbert's accounting trolls, this program actually engenders undefined behavior.

Alberto M
  • 1,057
  • 8
  • 24
10

If RAND_MAX is 32767, you can double the number of bits easily.

int BigRand()
{
    assert(INT_MAX/(RAND_MAX+1) > RAND_MAX);
    return rand() * (RAND_MAX+1) + rand();
}
Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • 1
    I don't think this works. Pseudo random number generators are typically deterministic. For example, if first `rand` call returns `0x1234` and second `0x5678`, then you get `0x12345678`. That is the **only** number that you can get that starts with `0x1234`, because next number will always be `0x5678`. You get 32-bit results, but you only have 32768 possible numbers. – user694733 Aug 22 '19 at 07:21
  • 1
    @user694733 a good random number generator has a period that's greater than the number of outputs it can generate, so 0x1234 won't *always* be followed by 0x5678. – Mark Ransom Aug 22 '19 at 13:44
8

If you are concerned about randomness and not about speed, you should use a secure random number generation method. There are several ways to do this... The easiest one being to use OpenSSL's Random Number Generator.

You can also write your own using an encryption algorithm (like AES). By picking a seed and an IV and then continuously re-encrypting the output of the encryption function. Using OpenSSL is easier, but less manly.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
SoapBox
  • 20,457
  • 3
  • 51
  • 87
  • I cannot use any third party library?I am restricted to C++ only. – anand Nov 13 '08 at 23:36
  • Then go the manly route, implement AES or some other encryption algorithm. – SoapBox Nov 13 '08 at 23:39
  • 2
    RC4 is trivial to code, and random enough for all practical purposes (except WEP, but that's not entirely RC4's fault). I mean it, it's incredibly trivial code. Like, 20 lines or so. The Wikipedia entry has pseudo-code. – Steve Jessop Nov 14 '08 at 01:21
  • 4
    Why can you not use third party code? If this is a homework question, you should say so, because many people would rather give helpful hints instead of providing complete solutions in this case. If it ain't a homework, go kick the guy who says "no 3rd party code", because he's a moron. – DevSolar Feb 02 '10 at 10:49
  • More direct link to the OpenSSL rand() function docs: http://www.openssl.org/docs/crypto/rand.html# – DevSolar Feb 02 '10 at 10:51
8

If you are able to, use Boost. I have had good luck with their random library.

uniform_int should do what you want.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jeff Thomas
  • 847
  • 2
  • 7
  • 9
  • I've done some work on uniform_int with a merseinne twister and unfortunately for certain ranges the values returned by uniform_int are not as uniform as I'd expect. For instance uniform_int<>( 0, 3 ) tends to produce more 0's than 1's or 2's – ScaryAardvark Feb 02 '10 at 11:12
  • @ScaryAardvark that sounds like a bad implementation of `uniform_int` then. It's quite easy to generate an unbiased output, there have been multiple questions here that demonstrate the method. – Mark Ransom Aug 22 '19 at 13:47
  • @Mark Ransom. Yes, I'd entirely agree. – ScaryAardvark Aug 23 '19 at 14:17
5

You should look at RAND_MAX for your particular compiler/environment. I think you would see these results if rand() is producing a random 16-bit number. (you seem to be assuming it will be a 32-bit number).

I can't promise this is the answer, but please post your value of RAND_MAX, and a little more detail on your environment.

Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
abelenky
  • 63,815
  • 23
  • 109
  • 159
3

Check what RAND_MAX is on your system -- I'm guessing it is only 16 bits, and your range is too big for it.

Beyond that see this discussion on: Generating Random Integers within a Desired Range and the notes on using (or not) the C rand() function.

Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
Rob Walker
  • 46,588
  • 15
  • 99
  • 136
  • Ok RAND_MAX is 32767. I am on C++ windows platform.. Is there any other method to generate random numbers with uniform distribution? – anand Nov 13 '08 at 23:35
3

This should provide a uniform distribution over the range [low, high) without using floats, as long as the overall range is less than RAND_MAX.

uint32_t rand_range_low(uint32_t low, uint32_t high)
{
    uint32_t val;
    // only for 0 < range <= RAND_MAX
    assert(low < high);
    assert(high - low <= RAND_MAX);

    uint32_t range = high-low;
    uint32_t scale = RAND_MAX/range;
    do {
        val = rand();
    } while (val >= scale * range); // since scale is truncated, pick a new val until it's lower than scale*range
    return val/scale + low;
}

and for values greater than RAND_MAX you want something like

uint32_t rand_range(uint32_t low, uint32_t high)
{
    assert(high>low);
    uint32_t val;
    uint32_t range = high-low;
    if (range < RAND_MAX)
        return rand_range_low(low, high);
    uint32_t scale = range/RAND_MAX;
    do {
        val = rand() + rand_range(0, scale) * RAND_MAX; // scale the initial range in RAND_MAX steps, then add an offset to get a uniform interval
    } while (val >= range);
    return val + low;
}

This is roughly how std::uniform_int_distribution does things.

benf
  • 915
  • 1
  • 9
  • 28
3

Using a Mersenne Twister engine (C++11):

#include <random>

// Returns a random integer within the range [min, max]
int generateRandomInt(const int min, const int max) {
  static bool is_seeded = false;
  static std::mt19937 generator;

  // Seed once
  if (!is_seeded) {
    std::random_device rd;
    generator.seed(rd());
    is_seeded = true;
  }

  // Use a Mersenne Twister engine to pick a random number
  // within the given range
  std::uniform_int_distribution<int> distribution(min, max);
  return distribution(generator);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
heothesennoc
  • 541
  • 5
  • 10
2

This is not the code, but this logic may help you.

static double rnd(void)
{
    return (1.0 / (RAND_MAX + 1.0) * ((double)(rand())));
}

static void InitBetterRnd(unsigned int seed)
{
    register int i;
    srand(seed);
    for(i = 0; i < POOLSIZE; i++)
    {
        pool[i] = rnd();
    }
}

 // This function returns a number between 0 and 1
 static double rnd0_1(void)
 {
     static int i = POOLSIZE - 1;
     double r;

     i = (int)(POOLSIZE*pool[i]);
     r = pool[i];
     pool[i] = rnd();
     return (r);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user3503711
  • 1,623
  • 1
  • 21
  • 32
2

If you want numbers to be uniformly distributed over the range, you should break your range up into a number of equal sections that represent the number of points you need. Then get a random number with a min/max for each section.

As another note, you should probably not use rand() as it's not very good at actually generating random numbers. I don't know what platform you're running on, but there is probably a better function you can call like random().

Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
Jason Coco
  • 77,985
  • 20
  • 184
  • 180
0

A solution

((double) rand() / (RAND_MAX+1)) * (max-min+1) + min

Warning: Don't forget due to stretching and possible precision errors (even if RAND_MAX were large enough), you'll only be able to generate evenly distributed "bins" and not all numbers in [min,max].


A solution using Bigrand

Warning: Note that this doubles the bits, but still won't be able to generate all numbers in your range in general, i.e., it is not necessarily true that BigRand() will generate all numbers between in its range.


Information: Your approach (modulo) is "fine" as long as the range of rand() exceeds your interval range and rand() is "uniform". The error for at most the first max - min numbers is 1/(RAND_MAX +1).

Also, I suggest to switch to the new random package in C++11 too, which offers better and more varieties of implementations than rand().

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ritualmaster
  • 206
  • 1
  • 9
0

By their nature, a small sample of random numbers doesn't have to be uniformly distributed. They're random, after all. I agree that if a random number generator is generating numbers that consistently appear to be grouped, then there is probably something wrong with it.

But keep in mind that randomness isn't necessarily uniform.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kluge
  • 3,567
  • 3
  • 24
  • 21
  • "uniformly distributed" has a well defined meaning, and the standard random generators usually come close. – peterchen Nov 14 '08 at 00:11
  • Yes, you are right, random number generators should produce output that *over time* is generally uniform in its distribution. I guess my point is that over a small number of instances (6 as shown in the example) the output won't always be uniform. – Kluge Nov 14 '08 at 00:20
  • Kluge is right. Uniform distribution in a small sample indicates that the sample is definitely *not* random. – Bill the Lizard Nov 14 '08 at 00:26
  • 1
    Bill, it indicates no such thing. Small samples are mostly meaningless, but if the RNG is supposed to be uniform and the output is uniform, why is that any worse than an non-uniform small sample? – Dan Dyer Nov 14 '08 at 00:41
  • 2
    Significant distributions either way indicate non-randomness: I think Bill just means that 6 equally-spaced results would also be suspect. In the OP, 6 values lie in a range of 32k/4M, or <1% of the desired range. The probability of this being a false positive is too small to argue over. – Steve Jessop Nov 14 '08 at 01:26
  • The odds of a uniform distribution over that range generating six values less than 32767 is ~0.000000000000000000000000000000007425% isn't it? Especially given the fact we have an alternative explanation besides chance.... – Mooing Duck Aug 01 '13 at 18:33
0

The solution given by man 3 rand for a number between 1 and 10 inclusive is:

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

In your case, it would be:

j = min + (int) ((max-min+1) * (rand() / (RAND_MAX + 1.0)));

Of course, this is not perfect randomness or uniformity as some other messages are pointing out, but this is enough for most cases.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
calandoa
  • 5,668
  • 2
  • 28
  • 25
  • 1
    This merely rearranges the distribution to _appear_ more even, but it's not actually any more even for large ranges (such as the OP's case) – Mooing Duck Aug 01 '13 at 18:30
0

This is the solution I came up with:

#include "<stdlib.h>"

int32_t RandomRange(int32_t min, int32_t max) {
    return (rand() * (max - min + 1) / (RAND_MAX + 1)) + min;
}

This is a bucket solution, conceptually similar to the solutions that use rand() / RAND_MAX to get a floating point range between 0-1 and then round that into a bucket. However, it uses purely integer math, and takes advantage of integer division flooring to round down the value to the nearest bucket.

It makes a few assumptions. First, it assumes that RAND_MAX * (max - min + 1) will always fit within an int32_t. If RAND_MAX is 32767 and 32 bit int calculations are used, the the maximum range you can have is 32767. If your implementation has a much larger RAND_MAX, you can overcome this by using a larger integer (like int64_t) for the calculation. Secondly, if int64_t is used but RAND_MAX is still 32767, at ranges greater than RAND_MAX you will start to get "holes" in the possible output numbers. This is probably the biggest issue with any solution derived from scaling rand().

Testing over a huge number of iterations nevertheless shows this method to be very uniform for small ranges. However, it is possible (and likely) that mathematically this has some small bias and possibly develops issues when the range approaches RAND_MAX. Test it for yourself and decide if it meets your needs.

Ryan
  • 1,670
  • 18
  • 25
0

Minimal implementation with C++11:

#include <random>

int randrange (int min, int max) {
    static std::random_device rd; // Static in case init is costly
    return std::uniform_int_distribution {min, max} (rd);
}
gatopeich
  • 3,287
  • 31
  • 26
0

This is an old thread, but I just stumbled on it now. Here's my take:

As others rightly pointed out, MSBs tend to be more randomly distributed than LSBs in most RNGs. That implies that taking the modulo (%) of rand() is doomed: e.g. the extremely frequent random(2) would only return the single LSB... which is extremely badly distributed in most RNGs. On the other hand, if you need your random(N) to be very fast (as I do: I'm in HPC and in heavily randomized GAs in particular), the modulo is cool for its speed.

Both of the above concerns can be addressed by (1) computing the (fast) modulo... of (2) rand()'s reversed bits.

-1

Of course, the following code won't give you random numbers, but pseudo random numbers.

Use the following code

#define QUICK_RAND(m,n) m + ( std::rand() % ( (n) - (m) + 1 ) )

For example:

int myRand = QUICK_RAND(10, 20);

You must call

srand(time(0));  // Initialize random number generator.

Otherwise the numbers won't be near random.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Michael Haephrati
  • 3,660
  • 1
  • 33
  • 56
  • 3
    The question is asking for a uniform distribution. This proposed solution will not produce a uniform distribution. The Standard C++ Library has facilities for [Pseudo-random number generation](https://en.cppreference.com/w/cpp/numeric/random). Those *do* provide uniform distribution, if requested. – IInspectable Aug 01 '19 at 14:02
-3

I just found this on the Internet. This should work:

DWORD random = ((min) + rand()/(RAND_MAX + 1.0) * ((max) - (min) + 1));
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
anand
  • 11,071
  • 28
  • 101
  • 159
  • 1
    Please clarify what you need them for, there are tons of algorithms for PRNG's out there. Also, it would be easier if you edit your main question instead of posting replies. – peterchen Nov 14 '08 at 00:33
  • This works best for me...I am able to get better distributed random numbers with this formula.. – anand Nov 14 '08 at 02:20
  • 5
    If your range exceeds RAND_MAX, the results may be *won't* be uniform. That is, there are values in the range that won't be represented no matter how many times in call your function. – dmckee --- ex-moderator kitten Nov 14 '08 at 03:45
  • 5
    Also, if max and min are both unsigned int, and min is 0, and max is MAX_UINT, then ((max)-(min)+1) will be 0, and the result will be 0 always. Watch out for overflow doing this type of math! As noted by dmckee, this stretches the distribution over destination range, but doesn't guarantee more than RAND_MAX unique values. – jesup Jan 06 '10 at 19:57