Generate a random number depending on input in a defined interval

I want to generate random numbers that deppend on input from user.

For example if user inputs 8, I want to generate number from 5 to 7, (8 - 3) to (8 - 1)

My code:

#include <iostream>
#include <time.h>

int main()
{

    int x1;
    int x2;

    std::srand(time(0));

    while (true)
    {
        std::cout << "input : ";
        std::cin >> x1;

        x2 = std::rand() % (x1 - 1) + (x1 - 3);

        std::cout << "result : ";
        std::cout << x2 << std::endl;
    }
    return 0;
}

But the output is:

input : 8
result : 7
input : 8
result : 10
input : 8
result : 8

And I want result to be from 5 to 7.

Answer

Addressing your problem

With the expression:

x2 = std::rand() % (x1 - 1) + (x1 - 3); 

Using your sample input, rand % (x1 - 1) will be rand % 7, this will render you values from 0 to 6, adding 5 to that you’ll have values from 5 to 11.

If you are adamant in using rand you can use something like this:

x2 = rand() / (RAND_MAX / ((x1 - 1) - (x1 - 3) + 1) + 1) + x1 - 3;

Live sample

The interval is corrected, and this is a less biased method of obtaining the random value than using the modulo, though this problem is never completely solvable when using rand, it’s a known drawback, there are others, you can find several threads in the website which provide solid reasoning as to why you shouldn’t use it, like, for instance:

Why is the use of rand() considered bad?

Why do people say there is modulo bias when using a random number generator?

You also have this more technical document kindly provided by njuffa:

Fast Random Integer Generation in an Interval

Among many others.


Recommend method

C++ <random> header provides better random number generation facilities, for example using std::random_device and the Mersenne twister engine:

#include <iostream>
#include <random>

int main()
{
    int x1;
    int x2;

    std::random_device rand_d; // random number from hardware
    std::mt19937 generator(rand_d()); // seed
    
    while (true)
    {
        std::cin >> x1;
        std::uniform_int_distribution<> uniform_value(x1 - 3, x1 - 1); // setup the range
        x2 = uniform_value(generator); // generante the value
        std::cout << "result : " << x2 << "n";
    }
}

Live sample

Leave a Reply

Your email address will not be published. Required fields are marked *