See the top rated post in this thread. Click here

Results 1 to 8 of 8

Thread: C question for Norm

  1. #1


    Did you find this post helpful? Yes | No

    C question for Norm

    Norm,

    When generating random numbers, one would use the rand() function from the standard library. This will output a random number from RAND_MIN to RAND_MAX. However; let's say one wants to restrict the range of all random numbers, say, for a die. You would want the restriction to be from 1 to 6; however, C allows the range to be from 0 to 5, so one could add one to the rand() function.

    Now, the question is: How would one restrict the range of random integers generated by the processor?

  2. #2
    Random number herder Norm's Avatar
    Join Date
    Dec 2011
    Location
    The mote in God's eye
    Posts
    12,461
    Blog Entries
    59


    Did you find this post helpful? Yes | No
    One would not use any compiler RNG. They are really embarrassingly poor.
    "I don't think outside the box; I think of what I can do with the box." - Henri Matisse

  3. #3


    Did you find this post helpful? Yes | No
    Norm is correct regarding use of the rand function (C stand library) or any of the PRNGs supplied by default with any other language.

    I don't know what platform you are on but the GNU Scientific Library (GSL) provides a nice framework for selecting a variety of much better PRNGs and for performing operations like the range limiting that you want to perform. In particular, GSL provides an implementation of the Mersenne Twister (mt19937). See https://www.gnu.org/software/gsl/man...ber-Generation

    Norm also posted some code for the MarzamII algorithm here

    https://www.blackjacktheforum.com/sh...zam#post110236

    which I was easily able to translate into C.

  4. #4


    1 out of 1 members found this post helpful. Did you find this post helpful? Yes | No

    Arrow

    On the separate topic of generating random numbers with a given range, you must be extremely careful. It is very easy to introduce an unwanted bias if you don't do this carefully.

    The most common error that inexperienced programmers tend to make is to simply use the modulo of the desired range. For example, in your case, you want numbers from 1 through 6 in order to simulate a die. Using the C formula (R % 6) + 1 would indeed give you numbers in this range, but they would be biased toward the lower numbers in the range. Can you see why?

    There is another method which involves converting the raw random number to a floating point number in the range [0-1) (i.e. from zero to just less than one) and then multiplying by the desired range, but this method is also biased in that, depending on the range, it may skip and/or favour some results in the range.

    The simplest correct method is to reject the results which caused the bias in the modulo method. That is, given a raw random number R, if R >= (PRNG_MAX + 1) / rangeSize * rangeSize (note the integer division), then reject it and generate another R. In this way, if the PRNG really is uniformly random, each of the bins representing your range will have equal probability of being selected. In your case, in C, assuming that the PRNG generates an integer in the range [0, PRNG_MAX] and that R and PRNG_MAX are integer types defined by the PRNG,

    Code:
    limit = (PRNG_MAX + 1) / 6 * 6; /* integer division */
    do {
      R = PRNG();
    } while (R >= limit);
    die = (R % 6) + 1; /* integer remainder */
    GSL uses this method, although it uses a more efficient implementation. Since GSL is open source, you can have a look at the source code to see how it is implemented.
    Last edited by Gronbog; 07-25-2016 at 12:54 PM. Reason: Cleaned up the code and fixed a bug

  5. #5


    Did you find this post helpful? Yes | No
    Quote Originally Posted by Gronbog View Post
    On the separate topic of generating random numbers with a given range, you must be extremely careful. It is very easy to introduce an unwanted bias if you don't do this carefully.

    The most common error that inexperienced programmers tend to make is to simply use the modulo of the desired range. For example, in your case, you want numbers from 1 through 6 in order to simulate a die. Using the C formula (R % 6) + 1 would indeed give you numbers in this range, but they would be biased toward the lower numbers in the range. Can you see why?
    Thanks G - good info - here's a funny story -

    I know enough about programming in Basic (or "Just Basic") to be dangerous. So I had some time on my hands a couple years ago and I wrote some programs to simulate my craps betting strategy and used the Rand function to simulate the dice rolls (int(rnd(0)*6) + 1). It showed that after a million rounds, I was a winner! Didn't make sense of course, so I tweaked the program to display the percentage occurrence of each rolled number. The number of 7s rolled was consistently less than 16.67%. Now there's my problem!

    So I set up another program using the Rand function, but I forced each "random" dice roll to fill an array of 1/6 of the total rolls. Yes - than I got the bad news about my strategy .

  6. #6


    Did you find this post helpful? Yes | No
    Quote Originally Posted by Bigdaddy View Post
    So I set up another program using the Rand function, but I forced each "random" dice roll to fill an array of 1/6 of the total rolls. Yes - than I got the bad news about my strategy .
    Just curious how you did that. If not done carefully, this sounds like it is the same as the biased modulo method.

  7. #7


    Did you find this post helpful? Yes | No
    Quote Originally Posted by Gronbog View Post
    Just curious how you did that. If not done carefully, this sounds like it is the same as the biased modulo method.
    This is so stupid I feel a little embarrassed telling you - but here's what I did...

    I set up arrays (r and k) with a million spots in each (i.e., dim r(1000000), dim k(1000000)). One million is the max size in the "Just Basic" program. Then I had the random number generator assign 1/6 of the spots in each array to each dice number (1-6). That way I knew that each dice number would appear an appropriate number of times, but they would be in randomly-assigned spots in the arrays. I did this using a subroutine for each dice number. For instance the subroutine for number 1 is as follows:
    sub random
    do while d1c1 < int(rolls/6)
    q = int(rnd(0)*rolls) + 1
    if r(q) = 0 then r(q) = 1:d1c1 = d1c1 + 1
    loop

    Then the million rolls of the dice would be determined by combining the numbers in the arrays; i.e., roll #1 would be r(1) + k(1) and so on through r(1000000) + k(1000000). That way I had a million random rolls!

    Please don't mark my paper with an "F" and send it back...my days as a novice programmer are over ...

  8. #8


    Did you find this post helpful? Yes | No
    Handling pseudo random numbers is tricky business. I won't post some of the things I did when I started.

Similar Threads

  1. Question for Norm
    By 21forme in forum General Blackjack Forum
    Replies: 3
    Last Post: 10-21-2014, 01:27 PM
  2. MJ: Question for Don or Norm regarding N0
    By MJ in forum Blackjack Main
    Replies: 8
    Last Post: 04-10-2007, 04:38 PM
  3. MJ: KO Question for Norm
    By MJ in forum Blackjack Main
    Replies: 12
    Last Post: 04-12-2006, 12:56 PM
  4. MJ: Question for Norm
    By MJ in forum Computing for Counters
    Replies: 5
    Last Post: 12-12-2005, 05:00 AM
  5. dog 21: question for Norm or Don
    By dog 21 in forum Blackjack Main
    Replies: 1
    Last Post: 11-25-2005, 10:48 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

About Blackjack: The Forum

BJTF is an advantage player site based on the principles of comity. That is, civil and considerate behavior for the mutual benefit of all involved. The goal of advantage play is the legal extraction of funds from gaming establishments by gaining a mathematic advantage and developing the skills required to use that advantage. To maximize our success, it is important to understand that we are all on the same side. Personal conflicts simply get in the way of our goals.