Results 1 to 13 of 13

Thread: Using C++ rand() isn't as bad as previously thought?

  1. #1
    Senior Member
    Join Date
    Jul 2004
    Location
    Des Moines, IA
    Posts
    1,254

    Default Using C++ rand() isn't as bad as previously thought?

    I was recently looking for the "right" way to use rand() since I had read about problems with using it incorrectly. The problem has to do with the lower order bits causing more repetition than expected, which ruins the randomness you could have. Uhfgood pointed me to the following article which seems to explain away the myths and gives a good solution to use: http://eternallyconfuzzled.com/articles/rand.html

    Well, I decided to test it for myself, and it turns out that the article seems to make claims that didn't pan out in my tests. Then again, maybe my tests weren't very accurate or didn't prove what I thought they did. The source code to my test is available, and I would appreciate it if someone else could verify the results for themselves.

    http://gbgames.com/blog/?p=538
    - Check out Stop That Hero!, a game in which you play the villain for once!
    - GBGames' Blog
    - Twitter: www.twitter/com/GBGames

  2. #2
    Senior Member
    Join Date
    Nov 2004
    Location
    Finland
    Posts
    503

    Default

    Just use Mersenne Twister and be done with it.

  3. #3

    Default

    rand() is a perfectly usable low-quality random number generator. You do need to be aware the issues with the low-order bits, but these are easily prevented by taking high-order bits when you have the choice anyway. For example:

    int foo = (rand() >> 8) & 65535;

    Will give you a decent random number from 0 to 65535.

    Saying the problems with rand() are myths is a bit like saying that the warning to hold a knife by the handle rather than the blade is a myth. It's no myth, but like many tools, there are caveats to their use. You hold a knife by the handle, and you hold rand() by the high bits. Also be aware that these problems are only present on some systems. Modern Linux distributions, for example, just call random() rather than rand(), which doesn't share the same problems.

    As Tertsi says, consider using a Mersenne Twister. They produce high-quality results at a fairly decent speed. It's actually hard to find a drawback. There's plenty of prewritten source out there. If you need ultra-fast psuedorandom number generation- and you'll know for sure if you do- chances are you're going to have to roll your own custom solution anyway.

    ... and Merry Christmas everyone.

  4. #4

  5. #5

    Default

    Quote Originally Posted by Garthy View Post
    rand() is a perfectly usable low-quality random number generator. You do need to be aware the issues with the low-order bits, but these are easily prevented by taking high-order bits when you have the choice anyway. For example:

    int foo = (rand() >> 8) & 65535;

    Will give you a decent random number from 0 to 65535.
    Just a sidenote - rand() returns a value within the range of 0-RAND_MAX which is usually/often 0x7FFF (don't know if it's defined by the standard or just an implementation detail). So just be prepared for a limited range of numbers.

  6. #6
    Senior Member
    Join Date
    Apr 2005
    Location
    Texas
    Posts
    137

    Default

    Another reason to roll your own rand() function is predictability across platforms. If you use the standard C library function, it could change with platform or compiler version (though not likely).

    Also, there are some reasons to wrap up your own random number generator in a class. By making separate random number objects for the game simulation vs. other parts of the game, you can support a synchronous multiplayer game model where the same simulation runs in sync on all machines. Not to mention it makes record/replay functionality much easier.
    -Spaceman Spiff
    Making games for the 6-year old in all of us

  7. #7

    Default

    Quote Originally Posted by Michael Flad View Post
    Just a sidenote - rand() returns a value within the range of 0-RAND_MAX which is usually/often 0x7FFF (don't know if it's defined by the standard or just an implementation detail). So just be prepared for a limited range of numbers.
    Yikes! I wasn't aware some implementations had limits so low. On the two Linux boxes I have on hand the limit is much higher (0x7FFFFFFF), but the thought of systems potentially being limited to 0x7FFF (32767 ie. only 15 bits!) is terrifying. Anyone know what various Windows systems are limited to? And idea which systems are limited to 0x7FFF?

    Personally, I just put together a class using a Mersenne Twister early on since I needed the predictability and the ability to have multiple separate streams of reproducible random numbers. If I use rand()- and I'm pretty sure I don't- it's only when I honestly don't care about the randomness at all.
    Last edited by Garthy; 12-25-2006 at 03:14 PM. Reason: Extra "n" fell out of Mersenne. ;)

  8. #8

    Default

    Maybe something like this would help for those who really don't want to use anything but rand(). It should cope with limits as low as 0x7FFF.

    Code:
    int rand2()
    {
      return ((rand() >> 7)&255)
           | (((rand() >> 7)&255) << 8)
           | (((rand() >> 7)&255) << 16)
           | (((rand() >> 7)&255) << 24);
    }
    This way you can pull out high-order bits even with a low RAND_MAX. Warning: Completely untested.

    Again, I'd rather just use a Mersenne Twister. Far less pain.

  9. #9
    Senior Member
    Join Date
    Oct 2006
    Posts
    176

    Default

    Quote Originally Posted by Spaceman Spiff View Post
    Another reason to roll your own rand() function is predictability across platforms. If you use the standard C library function, it could change with platform or compiler version (though not likely).
    I support this fully. You almost NEED to write your own rand() because you want deterministic code for the exact reasons you've mention -different platforms, different number generators, synchronization, etc.

    BTW using a random seed is a bad, bad, bad practice in games except for coverage testing.

  10. #10

    Default

    I have had problems with rand(), too. I think my problems stemmed from not ever in a million years imagining that RAND_MAX could be so small on some implementations.

    Use MT. It's easy to imagine that rand() is implemented very differently in different situations, which itself makes it kind of useless, e.g. say you are randomly generating levels based on some input seed. With rand() you can probably expect different levels on different platforms, which might not be what you want.
    www.venturethevoid.com Experimental Space Exploration RPG
    www.kittylambda.com K I T T Y * L A M B D A

  11. #11
    Member
    Join Date
    Dec 2006
    Location
    Barrington/UK or Boulder/USA
    Posts
    68

    Default

    Quote Originally Posted by voxel View Post
    I support this fully. You almost NEED to write your own rand() because you want deterministic code for the exact reasons you've mention -different platforms, different number generators, synchronization, etc.

    BTW using a random seed is a bad, bad, bad practice in games except for coverage testing.

    Hi everyone. I am designing a broswer based game rightnow and am using C++ for the platform.

    I've been reading Archives yesterday here and this one as well. My question is should I use something different than C++ for the platform or continue to
    use C++ ?

    Because so far I have'nt experienced any problems yet?

    I appreciate your help/inputs.
    Ferion by far is the best strategy game since 1999. Checkout the forum too. www.ferion.com

  12. #12
    Senior Member
    Join Date
    Aug 2004
    Location
    Austin, TX
    Posts
    110

    Default

    Take a look at Boost's random library. It offers a variety of RNG algorithms and utilities for shaping the distribution.

  13. #13

    Lightbulb Random Number Generation

    Quote Originally Posted by Spaceman Spiff View Post
    Another reason to roll your own rand() function is predictability across platforms. If you use the standard C library function, it could change with platform or compiler version (though not likely).
    I completely agree with Spaceman Spiff. From my own experience it is always best to use you own random number generator rather than rely on the one that comes with the compiler. It can be tricky to write your own one though and you have to be very careful so as to not create a broken generator. I've recently written an article about random number generation for games programmers that describes one of the most well tested generators and includes source in C and BASIC. I hope it will be useful to you:
    http://www.newkind.co.uk/articles/ga...om-numbers.php

    TTFN
    Christian.

Posting Permissions

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