Pokarface
Pokarface

Reputation: 41

How to generate negative random integer in c++

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

Answers (5)

Shafik Yaghmour
Shafik Yaghmour

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

orezvani
orezvani

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

Jerry Coffin
Jerry Coffin

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

Jon
Jon

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

Mike Seymour
Mike Seymour

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

Related Questions