### 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:

 ``12`` ``````New_Position_X = rand() % 601 + (-300); // -300 to 300 New_Position_Y = rand() % 601 + (-300); // -300 to 300 ``````

closed account (D80DSL3A)
`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.

 ``12345`` ``````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
 ``12345`` ``````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?
 ``1234`` ``````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.

 ``12345678910111213141516171819202122`` ``````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.

 ``1234`` ``````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

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.
closed account (D80DSL3A)
I kind of wondered about that.

Two solutions come to mind:
 ``123`` ``````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:
 ``1234567891011`` ``````#include #include #include // 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 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.

 ``1234567891011`` ``````#include #include #include // 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 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.