views:

78

answers:

3

i have to generate random numbers for 3 different cases. i. 1 dice ii. a pair of dice iii. 3 dices my questions: 1. please suggest me sm good logic to generate random numbers for all the 3 cases. 2. does the logic change when i consider the cses of 2 dices, rather than 1? 3.how much of an effect does the range in which we have to genrate a random number affect the logic of the random function?

+1  A: 

Since this sounds like homework I'm just going to give hints which should be "good enough" for you (a pro would do it slightly differently): use the random() function and the % (modulo) operator. Modulo is the "reminder" after a division.

DarkDust
It's `rand`, not `random`.
Matteo Italia
@Matteo Italia: On POSIX systems there's both: `int rand(void);` and `long random(void);`, both defined in `stdlib.h`. I got no idea about Windows, though.
DarkDust
As the TS speaks of dice, I'd like to note that using just "modulo" will yield a "loaded dice" due to MAX_RAND being not a multiple of 6. You can overcome this by using "modulo 8" instead of "modulo 6" and discarding numbers >= 6. More details can be found in "The Art of Programming" by Knuth, the chapter on random numbers (I don't remember the exact reference)
atzz
@DarkDust: I cheked it, and it's true that it's been defined in stdlib.h, but the *Conforming to* section of their manpages specifies that `rand()` conforms to `SVr4, 4.3BSD, C89, C99, POSIX.1-2001`, while `random()` to `4.3BSD, POSIX.1-2001`, so `random` seems to be just UNIX stuff. Nothing bad with it, but since the question was about C in general I thought it was better to use just C standard functions.
Matteo Italia
+2  A: 

Yea, like DarkDust said, this sounds like homework, so, to answer your questions with that in mind, I'd say:

--> No, the logic doesnt not change, no matter how many dices you include.

--> Easiest way to do this would be, just make a function that give you ONE
    random function, and depending on how many dices you have, call it that
    many times. 

--> You can instead include for loop in the function and add the values into 
    array and return the array.

This way, you can generate random number for 100 dices too.

iamserious
+2  A: 

If the range is small enough, you shouldn't have problems in using the usual modulo method

int GetRandomInt(int Min, int Max)
{
    return (rand()%(Max-Min+1))+Min;
}

(where Min a Max specify a closed interval, [Min, Max])

and calling it once for each dice roll. Don't forget to call srand(time(NULL)) at the start of the application (at the start only, not each time you want to get a random number) to seed the random number generator.

If the range starts to be bigger, you may have to face two problems:

First, the range of rand() obviously isn't [0, +∞), instead it's [0, RAND_MAX], where RAND_MAX is a #define guaranteed to be at least 32767. If your range (Max-Min) spans over RAND_MAX, then, with this method, you'll have some numbers that will have a zero probability of being returned.

This is more subtle: suppose that RAND_MAX is bigger than your range, but not that bigger, let's say that RAND_MAX==1.5*/(Max-Min). In this case, the distribution of results won't be uniform: rand() returns you an integer in the range [0, RAND_MAX] (and each integer in this range should be equiprobable), but you are taking the rest of the division with (Max-Min). This means that the numbers in the first half of your required range have twice the probability of being returned than the others: they can actually come from the first and the third third of the rand() range, while the second half of the required range can come only from the second third of the rand() range.

What does this mean for you?

Probably nothing. If all you want to do is a dice-roll simulator, you can go without problems with the modulo method, since the range involved is small, and the second problem, despite being still present, it's almost irrelevant: suppose your range is 3 and MAX_RAND 32767: from 0 to 32765, 0, 1 and 2 has the same probability, but going up to 32767 0 and 1 gain one potential exit, which is almost irrelevant, since they pass from a perfect 1/3 (10922/32766=0,333...) probability for each one to a 10922/32767 for 2 (~0,33332) and 10923/32767 (~0,33335) for 0 and 1 (assuming that rand() provides a perfect distribution).

Anyhow, to overcome such problems a quite used method is to "stretch" the rand() range over a wider range (or compressing it to a smaller range) using a method like this:

int GetRandomInt(int Min, int Max)
{
    return (int)(((double)rand())/MAX_RAND*(Max-Min))+Min;
}

based on the equivalence rand():MAX_RAND=X:(Max-Min). The conversion to double is necessary, otherwise the integer division between rand() and its maximum value will always yield 0 (or 1 in the rare case of rand()==MAX_RAND); it could be done in integer arithmetic performing the product first if MAX_RAND is small and the range too is not too wide, otherwise there's a high risk of overflow.

I suspect that, if the output range is bigger than the range of rand(), the "stretching" and the fp value truncation (due to the conversion to int) affect in some way the distribution, but just locally (e.g. in small ranges you may never get a certain number, but globally the distribution will look ok).

Notice that this method helps to overcome to a diffused limitation of the C standard library random number generator, i.e. the low randomness of the lower bits of the returned value - which are, incidentally, the ones you are using when you perform a modulo operation with a small output range.

However, keep in mind that the C standard library RNG is a simple one, that strives to comply with "easy" statistical rules, and as such is easily predictable; it shouldn't be used when "serious" random numbers are required (e.g. cryptography). For such needs there are dedicated RNG libraries (e.g. the RNG part of the GNU Scientific Library), or, if you need really random stuff, there are several real random number services (one of the most famous is this), which do not use mathematical pseudo-RNG, but take their numbers from real random sources (e.g. radioactive decay).

Matteo Italia
Excellent post.
DarkDust
thanx...dats exactly wat i was looking for.
wordwiz