20

just wondering, if I have the following code:

int randomNum = rand() % 18 + (-9);

will this create a random number from -9 to 9?

Danny
  • 9,199
  • 16
  • 53
  • 75

5 Answers5

36

No, it won't. You're looking for:

int randomNum = rand() % 19 + (-9);

There are 19 distinct integers between -9 and +9 (including both), but rand() % 18 only gives 18 possibilities. This is why you need to use rand() % 19.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • @Danny: See the expanded answer. It is based on the assumption that you want both -9 and +9 to be part of the range. If you don't, please clarify your requirements. – NPE Oct 25 '11 at 10:35
  • @Danny: since `rand() % 19 ` is always less than 19, the maximum value can be 18 and 18 - 9 is 9. – Prince John Wesley Oct 25 '11 at 10:36
  • 6
    nine negative numbers, nine positive and zero = 19 numbers. Just count aloud from -9 to +9 and check it. – Mawg says reinstate Monica Oct 25 '11 at 10:36
  • @Danny [-9,9] contains 19 numbers. Don't forget 0. – Shawn Chin Oct 25 '11 at 10:36
  • This is because the %18 will give you a value from 0-17 (as it is the remainder when divided by 18). 17-9 = 8, so the maximum value you can get with that would be 8, and not 9. – Jan S Oct 25 '11 at 10:36
  • @Danny: Because -9 to 9 are in fact 19 different numbers. Modulo 19 will allow numbers from 0 to 18. Also 19 different numbers. – b.buchhold Oct 25 '11 at 10:36
  • 2
    btw, why add negative nine? Why not just subtract nine? Sure, the compiler will do that anyway, but it just doesn't look right to me (ymmv) – Mawg says reinstate Monica Oct 25 '11 at 10:37
  • 7
    It's a common pattern to have `rand() % number_of_distinct_values + first_value`. If you think of it like that, it looks right. – R. Martinho Fernandes Oct 25 '11 at 10:39
  • @Mawg I'm trying to make a program to generate linear equations from -9 to 9. Thats why I needed the negatives, if that makes any sense :P – Danny Oct 26 '11 at 17:33
9

Do not forget the new C++11 pseudo-random functionality, could be an option if your compiler already supports it.

Pseudo-code:

std::mt19937 gen(someSeed);
std::uniform_int_distribution<int> dis(-9, 9);
int myNumber = dis(gen)
KillianDS
  • 16,936
  • 4
  • 61
  • 70
7

Your code returns number between (0-9 and 17-9) = (-9 and 8).

For your information

 rand() % N;

returns number between 0 and N-1 :)

The right code is

rand() % 19 + (-9);
Davide Aversa
  • 5,628
  • 6
  • 28
  • 40
3

You are right in that there are 18 counting numbers between -9 and 9 (inclusive).

But the computer uses integers (the Z set) which includes zero, which makes it 19 numbers.

Minimum ratio you get from rand() over RAND_MAX is 0, so you need to subtract 9 to get to -9.

The information below is deprecated. It is not in manpages aymore. I also recommend using modern C++ for this task.

Also, manpage for the rand function quotes:

"If you want to generate a random integer between 1 and 10, you should always do it by using high-order bits, as in

j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));

and never by anything resembling

j = 1 + (rand() % 10);

(which uses lower-order bits)."

So in your case this would be:

int n= -9+ int((2* 9+ 1)* 1.* rand()/ (RAND_MAX+ 1.));
nurettin
  • 11,090
  • 5
  • 65
  • 85
  • Interesting fact about generating random numbers with `rand()` – Shahbaz Oct 25 '11 at 11:48
  • Actually, [some other sources](http://linux.die.net/man/3/rand) quote that this issue is more or less historical. But there are other issues with the rand() func and other mathematical operations on it, such as that 13 numbres will have slightly higher chance of ocurring that 6 other numbers. If possible, use the new random generator functions from C++11 (or the boost alternatives) – KillianDS Oct 26 '11 at 17:18
0

Anytime you have doubts, you can run a loop that gets 100 million random numbers with your original algorithm, get the lowest and highest values and see what happens.

Petruza
  • 11,744
  • 25
  • 84
  • 136
  • This is so limited debugging. What if his code would somehow produce steps of 2, max and min could be correct, but the distribution wouldn't ... . Actually this only makes sense if you draw some kind of histogram – KillianDS Oct 25 '11 at 11:50
  • 1
    I am talking about the use of your test, which is about 0. The question was not about the boundaries, it was about "random numbers between -9 and 9" so I'd guess he won't be happy with missing 0 for example. – KillianDS Oct 26 '11 at 17:15
  • My test would have shown him that he was 1 off. That would have solved the error he made. – Petruza Oct 28 '11 at 21:04