Reputation: 41
I wrote a function that takes integers. It won't crash if the user types for example, -5, but it will convert it into positive =-(
int getRandoms(int size, int upper, int lower)
{
int randInt = 0;
randInt = 1 + rand() % (upper -lower + 1);
return randInt;
}
What should I change in the function in order to build random negative integers? The user inputs the range.
Upvotes: 1
Views: 3040
Reputation: 158529
There are two answers to this, if you are using C++11 then you should be using uniform_int_distribtion, it is preferable for many reasons for example Why do people say there is modulo bias when using a random number generator? is one example and rand() Considered Harmful presentation gives a more complete set of reasons. Here is an example which generates random integers from -5 to 5
:
#include <iostream>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 e2(rd());
std::uniform_int_distribution<int> dist(-5, 5);
for (int n = 0; n < 10; ++n) {
std::cout << dist(e2) << ", " ;
}
std::cout << std::endl ;
}
If C++11 is not an option then the method described in C FAQ in How can I get random integers in a certain range? is the way to go. Using that method you would do the following to generate random integers from [M, N]
:
M + rand() / (RAND_MAX / (N - M + 1) + 1)
Upvotes: 6
Reputation: 3785
You only need to sum to the lower-bound of the range [lbound, ubound]
:
int rangesize = ubound - lbound + 1;
int myradnom = (rand() % rangesize) + lbound;
Upvotes: 0
Reputation: 490238
You want to start by computing the range of the numbers, so (for example) -10 to +5 is a range of 15.
You can compute numbers in that range with code like this:
int rand_lim(int limit) {
/* return a random number in the range [0..limit)
*/
int divisor = RAND_MAX/limit;
int retval;
do {
retval = rand() / divisor;
} while (retval == limit);
return retval;
}
Having done that, getting the numbers to the correct range is pretty trivial: add the lower bound to each number you get.
Note that C++11 has added both random number generator and distribution classes that can take care of most of this for you.
If you do attempt to do this on your own, when you reduce numbers to a range, you pretty much need to use a loop as I've shown above to avoid skew. Essentially any attempt at just using division or remainder on its own almost inevitably introduces skew into the result (i.e., some results will happen more often than others).
Upvotes: 0
Reputation: 5335
You could also use Boost.Random, if you don't mind the dependency. http://www.boost.org/doc/libs/1_54_0/doc/html/boost_random.html
Upvotes: 0
Reputation: 254531
For a number in the closed range [lower,upper]
, you want:
return lower + rand() % (upper - lower + 1); // NOT 1 + ...
This will work for positive or negative values, as long as upper
is greater than or equal to lower
.
Your version returns numbers from a range of the same size, but starting from 1
rather than lower
.
Upvotes: 3