Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>So <code>rand()</code> is a pseudo-random number generator which chooses a natural number between 0 and <code>RAND_MAX</code>, which is a constant defined in <code>cstdlib</code> (see this <a href="http://en.cppreference.com/w/cpp/numeric/random/rand" rel="noreferrer">article</a> for a general overview on <code>rand()</code>).</p> <p>Now what happens if you want to generate a random number between say 0 and 2? For the sake of explanation, let's say <code>RAND_MAX</code> is 10 and I decide to generate a random number between 0 and 2 by calling <code>rand()%3</code>. However, <code>rand()%3</code> does not produce the numbers between 0 and 2 with equal probability! </p> <p><strong>When <code>rand()</code> returns 0, 3, 6, or 9,</strong> <code>rand()%3 == 0</code>. Therefore, P(0) = 4/11</p> <p><strong>When <code>rand()</code> returns 1, 4, 7, or 10,</strong> <code>rand()%3 == 1</code>. Therefore, P(1) = 4/11 </p> <p><strong>When <code>rand()</code> returns 2, 5, or 8,</strong> <code>rand()%3 == 2</code>. Therefore, P(2) = <strong><em>3/11</em></strong></p> <p>This does not generate the numbers between 0 and 2 with equal probability. Of course for small ranges this might not be the biggest issue but for a larger range this could skew the distribution, biasing the smaller numbers. </p> <p>So when does <code>rand()%n</code> return a range of numbers from 0 to n-1 with equal probability? When <code>RAND_MAX%n == n - 1</code>. In this case, along with our earlier assumption <code>rand()</code> does return a number between 0 and <code>RAND_MAX</code> with equal probability, the modulo classes of n would also be equally distributed.</p> <p>So how do we solve this problem? A crude way is to keep generating random numbers until you get a number in your desired range:</p> <pre><code>int x; do { x = rand(); } while (x &gt;= n); </code></pre> <p>but that's inefficient for low values of <code>n</code>, since you only have a <code>n/RAND_MAX</code> chance of getting a value in your range, and so you'll need to perform <code>RAND_MAX/n</code> calls to <code>rand()</code> on average.</p> <p>A more efficient formula approach would be to take some large range with a length divisible by <code>n</code>, like <code>RAND_MAX - RAND_MAX % n</code>, keep generating random numbers until you get one that lies in the range, and then take the modulus:</p> <pre><code>int x; do { x = rand(); } while (x &gt;= (RAND_MAX - RAND_MAX % n)); x %= n; </code></pre> <p>For small values of <code>n</code>, this will rarely require more than one call to <code>rand()</code>.</p> <hr> <p>Works cited and further reading:</p> <ul> <li><p><a href="http://www.cplusplus.com/reference/clibrary/cstdlib/rand/" rel="noreferrer">CPlusPlus Reference</a></p></li> <li><p><a href="http://eternallyconfuzzled.com/arts/jsw_art_rand.aspx" rel="noreferrer">Eternally Confuzzled</a> </p></li> </ul> <hr>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload