Maru
Maru

Reputation: 39

Why is the range of rand() smaller than that of int?

I am trying to fill a vector with 5000 random numbers. Each number is an integer. But I am wondering why rand() only gives positive integers, and also why it never gives the maximum values that an integer can hold. Is there a reason for that?

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

using namespace std;

int main()
{

unsigned seed = time(0);
srand(seed);

vector<int> vect(5000);

for (int i = 0; i < vect.size(); i++)
{
    vect[i] = rand();
}
return 0;
}

Upvotes: 0

Views: 755

Answers (3)

MSalters
MSalters

Reputation: 180010

The reason why you're not getting the full possible range is because rand() is ancient.

Back in the days when rand() was developed, the common way to implement a random-number generator was a so-called Linear Congruential Generator (lcg). This doesn't give very random numbers; in fact they're quite predictable if you've seen the first few. But computers back then were slow and worked on small numbers.

That's why rand() only promises 15 bits - the constant RAND_MAX defines the maximum value you can get from RAND, and it can be as low as 32767. 32 bit computers back then were not so common, so using 16 bits numbers made sense. And with common LCG implementations, the lowest bit was worthless (toggled between 0 and 1) so you wanted to discard that anyway.

Several decades of improvement have resulted in much better generators. In particular, the mt19937 generator is very good and still very efficient. Since 2011, C++ has <random> and it includes std::mt19937. Also, for convenience you can now pick your own distribution, with std::uniform_int_distribution<>(min,max)

Upvotes: 4

Tofu
Tofu

Reputation: 3613

As mentioned rand() is deprecated and should never be used in practical scenarios. But to answer your question as to why only positive integers, it's because producing a negative random integer is redundant so you can just use basic math to make a negative number out of the positive random number that was produced.

To give you an example: If I wanted to produce a random number between -5 and 27 completely arbitrary, I could just produce a random number between 0 and 32(inclusive) then subtract 5.

#include <stdio.h>
#include <stdlib.h>
int main(){

    int random = (rand() % 33) - 5;

    printf("%d",random);

    return 0;
}

Because this isn't a practical scenario I did not seed the random either. So you should not use this in your code but it holds true for pretty much any RNG function where you just subtract the negative range from your positive. You should however use the C++11 random number generator.

Upvotes: 3

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385295

Here's what rand() does:

Returns a pseudo-random integral value between ​0​ and RAND_MAX (0 and RAND_MAX included).

RAND_MAX is implementation defined but will be "at least 32767".

There is no "why" other than "this is how it is specified".

If you want a range that includes some negative numbers, you can apply some maths (for example, a subtraction).

Do note:

rand() is not recommended for serious random-number generation needs. It is recommended to use C++11's random number generation facilities to replace rand(). (since C++11)

Said facilities give you better control and better distribution (example).

Upvotes: 5

Related Questions