How to create a random number in intervals?

Hi guys. How do I generate a random number in intervals? Eg.(given a range from -300 to 300, I only want numbers in multiples of 5. So I want numbers like -215, -75, 10, 115, 160, 225 etc. I do not want numbers like -202, 103, 147 etc.)
My code currently only give any random number given a range:

1
2
New_Position_X = rand() % 601 + (-300); // -300 to 300
New_Position_Y = rand() % 601 + (-300); // -300 to 300 


I already have srand() btw
Follow your assignments with:
New_Position_X = ( New_Position_X/5)*5;
This should give the desired coarsening of the value.
Can you use % 5 on the number you have, then subtract that from the number will give a number in multiples of 5.

1
2
3
4
5
New_Position_X = rand() % 601 + (-300); // -300 to 300
New_Position_Y = rand() % 601 + (-300); // -300 to 300 

New_Position_X -= (New_Position_X % 5)   //multiple of 5 if New_Position_X is positive


You will need to sort out what happens when New_Position_X is negative.

HTH

Edit: fun2code solution is probably better.
Last edited on
1
2
3
4
5
New_Position_X = (rand() % 121 - 60) * 5;
/*rand() %121 gets you number in 0 – 120
 *(...) - 60 gets ypou number in -60 – 60
 *(...) * 5 gets you numer between -300 – 300
 */ 
Last edited on
@fun2code

I dont get it. Why would you divide it then multiply it by the same number? Wouldnt that give u the same number? Do u mean to ask me to do this?
1
2
3
4
New_Position_X = rand() % 601 + (-300); // -300 to 300
New_Position_Y = rand() % 601 + (-300); // -300 to 300

New_Position_X = ( New_Position_X/5)*5;


@TheIdeasMan

Lol ok thanks for the tip. My brain is a little fried after long hours of programming. It works thanks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
New_Position_X = rand() % 601 + (-300); // -300 to 300
New_Position_Y = rand() % 601 + (-300); // -300 to 300

		if (New_Position_X < 0)
		{
			New_Position_X -= (New_Position_X % 5);
		}

		else
		{
			New_Position_X += (New_Position_X % 5);
		}

		if (New_Position_Y < 0)
		{
			New_Position_Y -= (New_Position_Y % 5);
		}

		else
		{
			New_Position_Y += (New_Position_Y % 5);
		}


Edit sry that was wrong. Yours was right from the start. Dont need to handle negative values. if lets say i have -252 as the random number, then -252 % 5 = -2;
-252 - (-2) = -250; so i got a number that is multiple of 5.

1
2
3
4
New_Position_X = rand() % 601 + (-300); // -300 to 300
New_Position_Y = rand() % 601 + (-300); // -300 to 300 

New_Position_X -= (New_Position_X % 5);

Last edited on
@MiiNiPaa

Thanks for your input your codes work too thanks.
fun2code's solution works too, because it uses integer division.

252 / 5 is 50.

This is easier than what I proposed, IMO.

This all works because the numbers are ints (I hope - you haven't said). If you are using doubles, then you can make use of std::modf to get the integer part, cast that to an int, do the mod function as above, then cast it back to a double again.

http://en.cppreference.com/w/cpp/numeric/math/modf
I don't like to perform integer division/modulus operations on negative numbers. First, it is not defined by standarts. Second, current realisation in most processors going against math rules.
i.e.

20/10 = 2
19/10 = 1
...
10/10 = 1
9/10 = 0
...
0/10 = 0
-1/10 = 0 //Still 0!
....
-10/10=1
-11/10 = -1
-20/10 = -2

When we want to generate random number from -20 to 20 and get only numbers divisible by 10 by routine x = (rand() % 41 - 20) / 10 * 10 we will get:
2 or -2 with 1/40 chance
1 or -1 with 1/4 chance
0 with 19/40 chance

resulting random number will not be evenly distributed.
I kind of wondered about that.

Two solutions come to mind:
1
2
3
New_Position_X = rand() % 601;// positive number
New_Position_X -= New_Position_X%5;// do it while number is positive
New_Position_X -= 300;// now make it (possibly) negative 

2) 1st one is better.
C++11:
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <random>
#include <ctime>

// a random multiple of 5 in the inclusive range -300 to +300
int rand_in_interval()
{
    static std::mt19937 rng( std::time(nullptr) ) ;
    static std::uniform_int_distribution<int> distr( -60, +60 ) ;
    return distr(rng) * 5 ;
}

Good Work JLBorges

ThingsLearnt++;
Thanks for your input guys! Really appreciate it :)
At first my New_Position_X and New_Position_Y were of float type but i changed it to int to make life easier for me :P haha.

@JLBorges can i use this for floats and double? May need it for future use :D

> can i use this for floats and double?

Yes. Subject to the limitation that floating point is an inexact representation of a real number. For reasonably small integer values (like an integral value in the range -300 to +300), all you have to do is convert the result to a floating point type.

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <random>
#include <ctime>

// a random floating point multiple of 5 in the inclusive range -300 to +300
double rand_in_interval()
{
    static std::mt19937 rng( std::time(nullptr) ) ;
    static std::uniform_int_distribution<int> distr( -60, +60 ) ;
    return distr(rng) * 5 ; // the int is implicitly converted to a double
} 
@JLBorges

Thanks for the input :D Much appreciated
Topic archived. No new replies allowed.