0

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;
}
MSalters
  • 173,980
  • 10
  • 155
  • 350
Maru
  • 39
  • 4
  • 6
    The correct way to answer those question**s** might be to point you to [``](https://en.cppreference.com/w/cpp/header/random). – YSC Jul 23 '19 at 11:30
  • 2
    fyi: Mr STL on why rand is bad and the new https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful – Richard Critten Jul 23 '19 at 12:18

3 Answers3

5

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).

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
4

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)

MSalters
  • 173,980
  • 10
  • 155
  • 350
3

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.

Irelia
  • 3,407
  • 2
  • 10
  • 31
  • https://ericlippert.com/2013/12/16/how-much-bias-is-introduced-by-the-remainder-technique/ – Lightness Races in Orbit Jul 23 '19 at 11:45
  • Yes I believe bitshifting is alternatively faster and safer than modulating the result. – Irelia Jul 23 '19 at 11:50
  • @Nina i think you can set a range from a negative number to a positive for example from -5 to 10, if you use const int MAX_VALUE = 27 and const int MIN_VALUE = -5 and use this formula int random = (rand() % (MAX_VALUE - MIN_VALUE + 1)) + MIN_VALUE; – Maru Jul 23 '19 at 11:52
  • Yes @Maru the code I provided does the same thing only your example the code does the min and max calculation rather than you explicitly doing it. – Irelia Jul 23 '19 at 12:04