C rand() dice issue - c

I'm new to C and I'm reading a book about it. I just came across the rand() function. The book states that using rand() returns a random number from 0 to 32767. It also states that you can narrow the random numbers by using % (modulus operator) to do so.
Here is an example: the following expression puts a random number from 1 to 6 in the variable dice
dice = (rand() % 5) + 1;
I'm unable to get a remainder of 5 as any number from 0 to 33767 % 5 is equal to 0 to 4, but never 5.
Shouldn't it be % 6 in the above statement instead?
For example, if I choose randomly a number between 0 and 32767, let's say 75, then:
75 % 5 == 0
76 % 5 == 1
77 % 5 == 2
78 % 5 == 3
79 % 5 == 4
80 % 5 == 0
Etc.
So regardless of the random number between 0 and 32767, the remainder will never be 5, so it will not be possible to get a 6 number for the dice (as per the above statement).
Not sure if you will understand what I mean but your help would be much appreciated.

dice = (rand() % 5) + 1;
This will generate a random number between 1 to 5, inclusive, as you have analyzed. The % 5 in the book is probably just a typo. To get 1 to 6 it needs to be % 6.

First you will have to understand how modulo (%) works. If you have say 10 and divide it by 5 you get 2 with a remainder of 0, hence the 10 % 5. The possible range of remainders you would get when you mod(modulo) 5 is 0 - 4. Remember that the possible remainders would can get when you divide by x if from 0 to x-1. So in your case with the dice program you need numbers from the range of 1 to 6 (the faces of a die) hence you would mod 6 and add 1 to this number for give the necessary shift. (rand() % 6) + 1

Related

In SQL Server what function or calculation does the % sign perfrom in this statement if #RecCtr % 10000 =0

I tried running #RecCtr % 10000 this by setting different values for #RecCtr
I can see that if the value is 250000 then #RecCtr % 10000 will return zero and if i set the value of #RecCtr to 250111 for example, '#RecCtr % 10000' will return 111, can someone please shed some light on what does % do in this case. Thanks
It is a remainder operation (modulus).
So if you take
10 / 2 = 5 with remainder 0, your answer is 0
10%2=0
If you take 11 / 2 = 5 with remainder 1 your answer is 2
12%2=1
If we try 13/5 = 2 with remainder of 3, thus the answer would be 3

Generate random even number in range [m, n]

I was looking for C code to generate a set of random even number in range [start, end]. I tried,
int random = ((start + rand() % (end - start) / 2)) * 2;
This won't work, for example if the range is [0, 4], both 0 & 4 included
int random = (0 + rand() % (4 - 0) / 2) * 2
=> (rand() % 2) * 2
=> 0, 2, ... (never includes 4) but expectation = 0, 2, 4 ...
On the other hands if I use,
int random = ((start + rand() % (end - start) / 2) + 1) * 2;
This won't work, for example,
int random = (0 + (rand() % (4 - 0) / 2) + 1) * 2
=> ((rand() % 4 / 2) + 1) * 2
=> 2, 4, ... (never includes 0) but expectation = 0, 2, 4 ...
Any clue? how to get rid of this problem?
You complicated it too much. Since you're using rand() and the modulo operator, I'm assuming that you will not be using this for cryptographic or security purposes, but as a simple even number generator.
The formula I have found for generating a random even number in the range of [0, 2n] is to use
s = (rand() % (n + 1)) * 2
An example code:
#include <stdio.h>
int main() {
int i, s;
for(i = 0; i < 100; i++) {
s = (rand() % 3) * 2;
printf("%d ", s);
}
}
And it gave me the following output:
2 2 0 2 4 2 2 0 0 2 4 2 4 2 4 2 0 0 2 2 4 4 0 0 4 4 4 2 2 2 4 0 0 0 4 0 2 2 2 2 0 0 0 4 4 2 4 4 4 0 4 2 2 4 4 0 4 4 2 2 0 0 4 0 4 4 2 0 2 4 0 0 0 0 4 0 4 4 0 4 2 0 0 4 4 0 0 4 4 2 0 0 4 0 2 2 2 0 0 4 0 2 4 2
Best regards!
rand() % x will generate a number in the range [0,x) so if you want the range [0,x] then use rand() % (x+1)
Common notation for ranges is to use [] for inclusive and () for exclusive, so [a,b) would be a range such that a is included but not b.
So in your case, just use (rand() % 3)*2 to get random numbers among {0,2,4}
If you want even numbers in the range [m,n], then use ((m/2) + rand() % ((n-m+2)/2))*2
I do not trust in the mod operator for random numbers. I prefer
start + ((1 + stop - start) * rand())
/ (1 + RAND_MAX)
which only relies on the distribution of rand() in the interval
[0, .. , RAND_MAX] and not on any distribution of rand()%n in the
interval [0, .. , n-1].
Note: If you use this expression you should add appropriate casts to avoid multiplication overflow.
Note also
ISO/IEC 9899:201x (p.346):
There are no guarantees as to the quality of the random sequence produced and some implementations are known to produce sequences with distressingly non-random low-order bits. Applications with particular requirements should use a generator that is known to be sufficient for their needs.
Just and-out the low bit, which makes it even:
n= (rand()%N)&(-2);
and to use a start/stop (a range), the values can be offset:
int n, start= 5, stop= 20+1;
n= ((rand()%(stop-start))+start)&(-2);
The latter calculation generates a random number between 0 and RAND_MAX (this value is library-dependent, but is guaranteed to be at least 32767).
If the stop value must be included in the range of generated numbers, then add 1 to the stop value.
It takes that value modulo the stop value plus the start value, and then adds the start value. The value is now within the range of [start, stop]. As only even numbers are required, the low bit is anded-out because even numbers start at 2.
The anding-out is performed by generating a mask of all 1's, except the lowest bit. As -1 is all 1's (0xFFF...FFFFF), -2 is all 1's except this low bit (0xFFF...FFFFE). Next the bitwise AND operation (&) is perfomed with this mask and the number is now in the range [start,stop]. QED.

generate random number in a range [l u] [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to generate a random number from within a range - C
I saw the following code from programming pearls
int randint(int l, int u)
{ return l + (RAND_MAX*rand() + rand()) % (u-l+1);
}
Can anyone help me explain it?
Can we just use
return l + rand() % (u-l+1);
Thanks,
The problem with using rand() % n to get a number between 0 and n-1 is that it has some bias when n is not an exact divisor of RAND_MAX. The higher the value of n, the stronger this bias becomes.
To illustrate why this happens, let's imagine that rand() would be implemented with a six-sided die. So RAND_MAX would be 5. We want to use this die to generate random numbers between 0 and 3, so we do this:
x = rand() % 4
What's the value of x for each of the six outcomes of rand?
0 % 4 = 0
1 % 4 = 1
2 % 4 = 2
3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
As you can see, the numbers 0 and 1 will be generated twice as often as the numbers 2 and 3.
When your use case doesn't permit bias, this is a better way to calculate a random number:
(int)((double)rand() / (double)RAND_MAX * (double)n)
yes that is ok, check that u>l and you can do only this:
return l + (RAND_MAX*rand()) % (u-l+1);
explaination:
if we would like to generate in union distribution a random integer number in [0,N] when N>0 we would use:
return (RAND_MAX*rand()) % (N+1);
since the range is shitted with a constant value l in your case we just have to add it to the final result.
python model:
>>> import random
>>> import sys
>>> for i in xrange(20):
int(random.random()*sys.maxint%4)
0
1
2
3
1
1
2
2
3
0
3
3
0
2
3
3
1
2
2
3

Excercise in "C Programming: A modern Approach"

if anyone could answer me why this works, it would be greatly appreciated. The exercise (chapter 4, ex 7 and 8) says that if you have the expression:
9 - ((total - 1) % 10)
then, you could be tempted to simplify it like this:
10 - (total % 10)
But this would not work. Instead he offers the alternative:
(10 - (total % 10)) % 10
Now, I understand how he got to the first simplification, but not why it's wrong, or why does the second one works.
Thanks in advance
x %m has a range of (-m, m) in most C implementations. Mathematically it is generally defined from (0, m). Hence by adding m the modulo again will convert the C to the mathematical one.
Consider the outputs for total = 10 to see that the second expression is not equivalent.
Note also that the third expression is not equivalent to the first expression unless total > 0 (because the behaviour of % is implementation-defined in pre-C99 C, and defined but not what you want in C99).
Assuming that total > 0, the first and third expressions are equivalent due to the following mathematical identity:
(a % b) == (((a + c) % b) - c) % b
To understand why, imagine doing the operations on a clock-face.
This is because modulo in C allows for negative numbers.
so -5 % 10 is -5 instead of 5.
In the first case, the 9 - ((total - 1) % 10) is always positive.
In the second case it can be negative if -10 < total < 0. In the 3rd case it is again wrapped around for negatives back into the positive range.
It is a common thing for modulo because generally you want it for positives only(not sure why they implemented it for negatives).
To show why 9-((total)%10) is wrong, use a contradiction.
Let total = 10.
Then 9-((10-1)%10) ==> 9-(9%10) ==> 9-9 = 0.
But, 10-(10%10) ==> 10 -0 = 10.
Thus, 10-((total)%10) is not equivalent to 9-((total-1)%10)
The alternative is not a simplification and neither expression is equvalent to the first so the premise is flawed from the start:
The following:
int total ;
for( total = -10; total <= 10; total++ )
{
printf( "%d:\t%d\t%d\t%d\n", total,
9 - ((total - 1) % 10),
10 - (total % 10),
(10 - (total % 10)) % 10 ) ;
}
Produces:
-10: 10 10 0
-9: 9 19 9
-8: 18 18 8
-7: 17 17 7
-6: 16 16 6
-5: 15 15 5
-4: 14 14 4
-3: 13 13 3
-2: 12 12 2
-1: 11 11 1
0: 10 10 0
1: 9 9 9
2: 8 8 8
3: 7 7 7
4: 6 6 6
5: 5 5 5
6: 4 4 4
7: 3 3 3
8: 2 2 2
9: 1 1 1
10: 0 10 0
The last is only equvalent for integers greater than zero.

How does modulus of a smaller dividend and larger divisor work?

7 % 3 = 1 (remainder 1)
how does
3 % 7 (remainder ?)
work?
remainder of 3/7 is 3..since it went 0 times with 3 remainder so 3%7 = 3
7 goes into 3? zero times with 3 left over.
quotient is zero. Remainder (modulus) is 3.
Conceptually, I think of it this way. By definition, your dividend must be equal to (quotient * divisor) + modulus
Or, solving for modulus: modulus = dividend - (quotient * divisor)
Whenever the dividend is less than the divisor, the quotient is always zero which results in the modulus simply being equal to the dividend.
To illustrate with OP's values:
modulus of 3 and 7 = 3 - (0 * 7) = 3
To illustrate with other values:
1 % 3:
1 - (0 * 3) = 1
2 % 3:
2 - (0 * 3) = 2
The same way. The quotient is 0 (3 / 7 with fractional part discarded). The remainder then satisfies:
(a / b) * b + (a % b) = a
(3 / 7) * 7 + (3 % 7) = 3
0 * 7 + (3 % 7) = 3
(3 % 7) = 3
This is defined in C99 ยง6.5.5, Multiplicative operators.
7 divided by 3 is 2 with a remainder of 1
3 divided by 7 is 0 with a remainder of 3
As long as they're both positive, the remainder will be equal to the dividend. If one or both is negative, then you get reminded that % is really the remainder operator, not the modulus operator. A modulus will always be positive, but a remainder can be negative.
(7 * 0) + 3 = 3; therefore, the remainder is 3.
a % q = r means there is a x so that q * x + r = a.
So, 7 % 3 = 1 because 3 * 2 + 1 = 7,
and 3 % 7 = 3 because 7 * 0 + 3 = 3
It seems you forgot to mention the surprising case, if the divident is smaller and negative:
-3 % 7
result: 4
For my brain to understand this kind of question, I'm always converting it to a real world object, for example if I convert your question 3 % 7. I'm going to represent the "3" as a 3-inch wide metal hole, then the "7" as a 7 inch metal screw. Can you insert the 7 inch metal screw to a 3 inch wide metal hole? Of course not, therefore the answer should be the 3-inch metal hole, it doesn't matter even let say you have a 1000 or a million inch wide screw, it is still 3, because how many times can you insert the 1000 or a million inch wide screw to a 3 inch wide metal hole? Zero times, right?
The most simple and effective catch to remember would be:
Whenever dividend is less than the divisor, modulus is just that dividend.
Let's formulate this:
if x < y, then x % y = x

Resources