Learning C++, Random Number Generator

Discussion in 'Programmer's Corner' started by sailmike, Aug 15, 2015.

  1. sailmike

    Thread Starter Member

    Nov 11, 2013
    143
    3
    I'm trying to use "rand" and "srand" to generate random numbers between 1 and 2 and then assigning heads to 1 and tails to 2 to simulate a coin flip. The explanation is probably just a bit of math I think. I need a better explanation of the following line:

    return rand() % (high - low + 1) + low;

    I'm not sure how "rand()" works or the use of %. I've attached the program as a text file.

    Thanks,
    Mike
     
  2. nsaspook

    AAC Fanatic!

    Aug 27, 2009
    2,908
    2,169
    The function srand(key) provides the 'seed' that rand will use to generate a repeating sequence of 'random' numbers.
    % is the modulus operator.
    http://www.cprogramming.com/tutorial/modulus.html

    You would get the remainder of the low binary bits from rand() % some large number.
    The stock C++ rand modulo operation is not a very good generator if you plan for the coin flip to be truly random. The low bit distribution is very weak.
     
  3. Papabravo

    Expert

    Feb 24, 2006
    10,145
    1,791
    A good random number generator is an extraordinarily hard thing to get right. Knuth has written exhaustively on the subject in Volume 2 of, The Art of Computer Programming

    http://www.informit.com/articles/article.aspx?p=2221790


    Try the exercises if you have the intestinal fortitude.
     
  4. vpoko

    Member

    Jan 5, 2012
    258
    47
    rand() will return a pseudo-random integer between 0 and some large number (how large depends on the value of a constant, RAND_MAX, found in stdlib.h).

    % is the modulo operator. "a % b", read as "a mod b", means divide a by b, and ignoring the whole part, return the remainder.

    For example 7 % 4 means divide 7 by 4 and return the remainder, which is 3. We do this intuitively with clock math. When an analog clock reads 10:00, you know that adding 5 hours will make it show 3:00. That's because 10 + 5 = 15, and 15 % 12 = 3.

    The point of it is to place an upper bound on some number and have it "start from the beginning" if it gets above that number. By doing "rand() % n" you'll get a number between 0 and n-1 (not with a perfectly equal probability for various reasons).

    The code you have places both an upper and a lower bound (returns a number between low and high). It might look confusing, but once you consider order of operations, it makes sense. First what's inside the parenthesis (high - low + 1) is evaluated, then the % is evaluated, and finally low is added to the result. If you're still confused, pick low and high numbers in your head, then pick a "random" number (also in your head) somewhat bigger than the high, and work out the math on paper.
     
    Last edited: Aug 16, 2015
  5. Kermit2

    AAC Fanatic!

    Feb 5, 2010
    3,791
    945
    for more random than a single rand function, place the rand function in a for next loop that uses a rand function to determine the number of loops and then take the your random number from the rand function after it has been executed and discarded a random number of times before returning the value.
     
  6. Papabravo

    Expert

    Feb 24, 2006
    10,145
    1,791
    There is no reason to suspect the result would have better random properties than the underlying psedo-random sequence, although it may be tempting to posit that suggestion.
     
  7. vpoko

    Member

    Jan 5, 2012
    258
    47
    Indeed. I think randomness is a an area where intuition tends to fail.

    In any case sailmike, for your purposes, the stock c rand() function is more than random enough.
     
    Last edited: Aug 16, 2015
  8. Papabravo

    Expert

    Feb 24, 2006
    10,145
    1,791
  9. sailmike

    Thread Starter Member

    Nov 11, 2013
    143
    3
    I forgot to mention that my code doesn't compile. There are some errors:


    warning C4244: 'argument': conversion from 'time_t' to 'unsigned int', possible loss of data
    error C2446: '==': no conversion from 'int' to 'int (__cdecl *)(int,int)
    note: Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
    error C2040: '==': 'int (__cdecl *)(int,int)' differs in levels of indirection from 'int'

    Whoops, I just noticed that I declared heads and tails double numbers instead of integers. It still doesn't compile though.

    Thanks,
    Mike
     
  10. vpoko

    Member

    Jan 5, 2012
    258
    47
    Sailmike, randrange is a function, so you'd have to change if (randrange == 1) to if (randrange(1, 2) == 1).

    But because you call randrange above, and want to reuse the result instead of re-evaluating, what you need do is create a variable to assign the return value of randrange the first time you call it, and then compare that variable in the if statement.
    Code (Text):
    1. // Somewhere outside your for loop.
    2. int rng;
    3.  
    4. // Inside your for loop.
    5. rng = randrange(1, 2);
    6. cout << rng << '\n';
    7. if (rng ==1)
    8. ...
     
    Last edited: Aug 17, 2015
  11. sailmike

    Thread Starter Member

    Nov 11, 2013
    143
    3
    That compiled and ran fine. Thank you!

    Could part of the problem be that I had the numbers backwards? As in randrange(3, 2) instead of randrange(2, 3)?

    I understand your explanation.

    Mike
     
    Last edited: Aug 17, 2015
  12. vpoko

    Member

    Jan 5, 2012
    258
    47
    Let's work out what happens with randrange(3, 2)...

    The statement would look like: return rand() % (2 - 3 + 1) + 3;
    The part inside the parenthesis would evaluate to 0, so it would try rand() % 0 (before adding the 3), and you can't mod by 0 for the same reason that you can't divide by 0, so it would fail at runtime with a divide-by-zero error or something akin to it. It wouldn't fail to compile, though, since it wouldn't evaluate the function until it's actually called, which doesn't happen until you run the program.
     
    Last edited: Aug 17, 2015
  13. Moon968

    New Member

    Apr 14, 2014
    10
    0
  14. djsfantasi

    AAC Fanatic!

    Apr 11, 2010
    2,809
    834
Loading...