Thread: Random Number Issues

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    4

    Random Number Issues

    So. What I am attempting to do is to get the program to spit out a random number somewhere between 1 and 10,000. It's not working quite the way I want, specifically, the numbers end up being low, for some reason.

    Basically, I just ran a loop 10,000 times, where the program kept spitting out random numbers (1-10000) and every time made a note of whether or not the random number was above or below the middle number (5000 in this case.) The program consistently spits out numbers from 1-10000 that are only 5001 or above maybe 4500 times out of 10000. Which is just plain out bizarre. I ran the same program for numbers 1-6 and it came right down the middle, around 5000 of the 10000 numbers were 4+.

    What am I doing wrong? (It is possible that this is actually a malfunction of the testing function, and not the generator itself, but that in and of itself would be interesting to know.)

    Thanks for your patience, trying to learn C++ quickly to test some things out that can't be done in a spreadsheet.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    If you post the code, we can possibly comment on whether you are doing something wrong in your code. And of course, different C compilers have different (quality of) random number generators, so if you tell us which compiler/OS you are using, someone may be able to tell whether this is what can be expected.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    Why should it be even? If a random number generator spits out 4 for ten thousands rounds that wouldn't make it less random.*

    That asked, why don't you post what you have?!

    Soma

    *(I only bring this up because PRNG basically sample a few bits at a time from some huge number. Depending on the algorithm, you are guaranteed to occasion upon an "area" of the expansion that returns the same number for "a very long time".)

    link: http://eternallyconfuzzled.com/arts/jsw_art_rand.aspx
    Last edited by phantomotap; 05-15-2009 at 04:48 PM.

  4. #4
    Registered User
    Join Date
    May 2009
    Posts
    4
    int x, z;
    time_t seconds;
    time(&seconds);
    z=0;
    srand((unsigned int) seconds);
    for (int y=0;y<10000;y++)
    {
    x=rand() % (5000) +1 ;
    if (x>=2500) {z++;}
    }

  5. #5
    Registered User
    Join Date
    Jan 2009
    Posts
    31
    If you're using the % modulus operator to range your random numbers from rand, then this would be the issue. Why?

    Suppose that the distribution from rand() is completely uniform from 0 to RAND_MAX. With some systems, I believe RAND_MAX is about 32767. Since the top is at 32767, and not some number evenly divisible by 10000, numbers from 0 - 2767 are more likely to occur. It's about 1.33 times more likely to get a number 2767 or below than any number above.

    Edit: I see that you are using the modulus operator.

    A better conversion:

    int r = (rand() * 5000) / (RAND_MAX + 1);

    The only issue is that you might need to be careful of overflow if the implementation yields large numbers from rand().
    Last edited by tjb; 05-15-2009 at 04:58 PM.

  6. #6
    Registered User
    Join Date
    May 2009
    Posts
    4
    Honestly, what I want is to figure out how to get my consistently random 1-10000 numbers. Troubleshooting what I have is good, but if someone knows how to do it in a different way, I'm all about that. I've read a lot of mixed information on the best way to do random numbers, so I'm mostly winging it. I'm running the Code::Block 8.02 compiler, for what it is worth.

    Again, thanks for bearing with me

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by sansterre View Post
    Thanks for your patience, trying to learn C++ quickly to test some things out that can't be done in a spreadsheet.
    You mean, you haven't yet figured out that you could fill 4000 rows of a spreadsheet with random numbers (ok, so the formula to make a 1..10000 number would be something like this: =int(10000 * rand() + 1), and then you do =countif(A1:A4000, ">5000").

    As Soma says, the distribution of random numbers in C/C++ is not guaranteed to be equal on both sides of the middle. If you want that for a serious reason, then perhaps you should be looking for a "real" pseudo-random number generator. Mersenne-Twister is a few dozen lines of code - available on the Web by the original authors that came up with the algorithm.

    For simple games and simulatiokns (and rather complex ones, for that matter), rand() is usually fine. For something that is commercially important (e.g. games of chance for real money on a website) you want something that is slightly less predictable.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Jan 2009
    Posts
    31
    Here's a quick comparison of the different ways of scaling the output of rand()

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int y = 0;
        for(; y < 5; y++) {
            printf("Trial %d\n", y);
            int r1 = 0, r2 = 0;
    
            int x = 0;
            for(; x < 10000; x++) {
                if(rand() % 10000 >= 5000) r1++;
            }
    
            for(x = 0; x < 10000; x++) {
                if((rand() * 10000) / (RAND_MAX + 1) >= 5000) r2++;
            }
    
            printf("Results for rand() %% 10000: %d\n", r1);
            printf("Results for (rand() * 10000) / (RAND_MAX + 1): %d\n\n", r2);
        }
    
        return 0;
    }
    And the results:
    Trial 0
    Results for rand() % 10000: 4557
    Results for (rand() * 10000) / (RAND_MAX + 1): 5090

    Trial 1
    Results for rand() % 10000: 4575
    Results for (rand() * 10000) / (RAND_MAX + 1): 5036

    Trial 2
    Results for rand() % 10000: 4563
    Results for (rand() * 10000) / (RAND_MAX + 1): 5041

    Trial 3
    Results for rand() % 10000: 4546
    Results for (rand() * 10000) / (RAND_MAX + 1): 4976

    Trial 4
    Results for rand() % 10000: 4552
    Results for (rand() * 10000) / (RAND_MAX + 1): 5028

    It's clear that the scaling method is significant.

  9. #9
    Registered User
    Join Date
    May 2009
    Posts
    4
    Tjb, thank you. Your suggested alterations seem to work perfectly.

    Much appreciated,

    Sansterre

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. adding a number to a number
    By bigmac(rexdale) in forum C Programming
    Replies: 11
    Last Post: 10-24-2007, 12:56 PM
  2. How exactly does the random number generator work?
    By Finchie_88 in forum C++ Programming
    Replies: 6
    Last Post: 08-24-2007, 12:46 AM
  3. Issue w/ Guess My Number Program
    By mkylman in forum C++ Programming
    Replies: 5
    Last Post: 08-23-2007, 01:31 AM
  4. Counting number from a random file
    By kamisama in forum C Programming
    Replies: 42
    Last Post: 02-22-2005, 05:16 PM
  5. How do I restart a random number sequence.
    By jeffski in forum C Programming
    Replies: 6
    Last Post: 05-29-2003, 02:40 PM