Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Function for random number 'between limits' - how?

Function for random number 'between limits' - how?

Scheduled Pinned Locked Moved C / C++ / MFC
questionlounge
13 Posts 8 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    James Millson
    wrote on last edited by
    #1

    Can anybody point me towards a function that's something along the lines of:

    int32 GetRandomNumberBetween(int32 nLower, int32 nUpper)
    {
    // generate random number between upper and lower bounds here...

    return nTheRandomNumber;
    

    }

    I just can't get it right myself, and I can't find one anywhere on the net or in my books. Yours, James Millson

    B L T A PJ ArendsP 6 Replies Last reply
    0
    • J James Millson

      Can anybody point me towards a function that's something along the lines of:

      int32 GetRandomNumberBetween(int32 nLower, int32 nUpper)
      {
      // generate random number between upper and lower bounds here...

      return nTheRandomNumber;
      

      }

      I just can't get it right myself, and I can't find one anywhere on the net or in my books. Yours, James Millson

      B Offline
      B Offline
      Ben Burnett
      wrote on last edited by
      #2

      Here is a quick and dirty one I hacked together from the CRT; static long random_number = 1L; // seed our pseudorandom number generator void SeedRandomNumber ( unsigned int seed ) { random_number = (long)seed; } // return a random number in the range [lower, upper] int GetRandomNumberBetween ( unsigned int lower, unsigned int upper ) { return ( ( ( ( random_number = random_number * 214013L + 2531011L ) >> 16 ) & ( upper - lower ) ) + lower ); } This is not thread safe, but should get you started. -Ben --------- On the topic of code with no error handling -- It's not poor coding, it's "optimistic" ;)

      T 1 Reply Last reply
      0
      • B Ben Burnett

        Here is a quick and dirty one I hacked together from the CRT; static long random_number = 1L; // seed our pseudorandom number generator void SeedRandomNumber ( unsigned int seed ) { random_number = (long)seed; } // return a random number in the range [lower, upper] int GetRandomNumberBetween ( unsigned int lower, unsigned int upper ) { return ( ( ( ( random_number = random_number * 214013L + 2531011L ) >> 16 ) & ( upper - lower ) ) + lower ); } This is not thread safe, but should get you started. -Ben --------- On the topic of code with no error handling -- It's not poor coding, it's "optimistic" ;)

        T Offline
        T Offline
        Tomasz Sowinski
        wrote on last edited by
        #3

        The trick with & will not work for majority of lower/upper pairs. For example: lower==0, upper==0x10000. The other thing is that CRT random generator returns 16-bit values. Tomasz Sowinski -- http://www.shooltz.com.pl

        B 1 Reply Last reply
        0
        • T Tomasz Sowinski

          The trick with & will not work for majority of lower/upper pairs. For example: lower==0, upper==0x10000. The other thing is that CRT random generator returns 16-bit values. Tomasz Sowinski -- http://www.shooltz.com.pl

          B Offline
          B Offline
          Ben Burnett
          wrote on last edited by
          #4

          Your right, I should have specified that the largest difference between the upper and lower bounds could not exceed a 16-bit value and that the generated number is limited to 16 bits as well. I supposed it depends on what he was using it for, personally I’ve never needed to use the functions for anything other that bogus test data for my app’s. Have a good one, -Ben --------- On the topic of code with no error handling -- It's not poor coding, it's "optimistic" ;)

          T 1 Reply Last reply
          0
          • B Ben Burnett

            Your right, I should have specified that the largest difference between the upper and lower bounds could not exceed a 16-bit value and that the generated number is limited to 16 bits as well. I supposed it depends on what he was using it for, personally I’ve never needed to use the functions for anything other that bogus test data for my app’s. Have a good one, -Ben --------- On the topic of code with no error handling -- It's not poor coding, it's "optimistic" ;)

            T Offline
            T Offline
            Tomasz Sowinski
            wrote on last edited by
            #5

            The problem with & isn't limited to low/high ranges greater than 16 bits. lower==0, upper==0x10 will also give you trouble when used with bitwise and operator. The generator will be returning 0 or 16. Tomasz Sowinski -- http://www.shooltz.com.pl

            1 Reply Last reply
            0
            • J James Millson

              Can anybody point me towards a function that's something along the lines of:

              int32 GetRandomNumberBetween(int32 nLower, int32 nUpper)
              {
              // generate random number between upper and lower bounds here...

              return nTheRandomNumber;
              

              }

              I just can't get it right myself, and I can't find one anywhere on the net or in my books. Yours, James Millson

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              I have written this function and it gives me a random number between [nMin..nMax] int RandBetween(int nMin, int nMax) { int r = (rand() * RAND_MAX + nMin) % nMax; if (r <= nMin) r = nMin+1; else if (r >= nMax) r= nMax-1; return r; } Mh2! :)

              M 1 Reply Last reply
              0
              • J James Millson

                Can anybody point me towards a function that's something along the lines of:

                int32 GetRandomNumberBetween(int32 nLower, int32 nUpper)
                {
                // generate random number between upper and lower bounds here...

                return nTheRandomNumber;
                

                }

                I just can't get it right myself, and I can't find one anywhere on the net or in my books. Yours, James Millson

                T Offline
                T Offline
                Tim Deveaux
                wrote on last edited by
                #7

                Ok, here's my try :) I decided to go the mundane inelegant math route (though I bet there are elegant ways to do this). This code computes a number in the range nLower to nUpper, and adds it to nLower. One major stumble is that you need to be able to store the range, so an int wont cut it. Also, this code has a problem, in that it returns numbers from nLower to nUpper-1. You can extend the range by 1 in most cases, but you run into snarky special case code. I'll leave it like this - season to taste.

                int GetRandomNumberBetween(int nLower, int nUpper){

                int              nTheRandomNumber = 0;
                unsigned int     range, offset;
                float            r;
                
                // assume nothing! (or do a min() max() thing)
                assert( nUpper >= nLower );
                
                // important that range be unsigned
                range = (nUpper - nLower);
                
                // RAND\_MAX may be smaller than int32 max, but the point is
                // only to get a number between 0 and 1
                r = (float)rand() / (float)RAND\_MAX;
                
                // offset may be 0 if both inputs are the same - which is ok
                offset = (int)(r \* range);
                
                nTheRandomNumber = nLower + offset;
                
                TRACE(\_T("nTheRandomNumber = %d\\n"), nTheRandomNumber);
                return nTheRandomNumber;
                

                }

                1 Reply Last reply
                0
                • J James Millson

                  Can anybody point me towards a function that's something along the lines of:

                  int32 GetRandomNumberBetween(int32 nLower, int32 nUpper)
                  {
                  // generate random number between upper and lower bounds here...

                  return nTheRandomNumber;
                  

                  }

                  I just can't get it right myself, and I can't find one anywhere on the net or in my books. Yours, James Millson

                  T Offline
                  T Offline
                  Tim Deveaux
                  wrote on last edited by
                  #8

                  I've gotten caught up in this - I think the code I posted above comes close, but I have the feeling that the distribution of values will be less than optimal for very large ranges. Here's something that might be of interest - I dug this out of my trusty ol 'Programming the Pet/CBM' by Raeto Collin West (best book I ever bought) - its a Gaussian formula for generating pseudo random numbers, of the form x = a * x + c (mod m) - (should be subscripts on the x's - but you get the idea - x is plugged back into the formula to get the next x). According to Gauss, the maximum period is obtained when a = 4*n + 1 and c is an odd number. I don't know this stuff well enough to tell you whether there is a particular a and c that should be used. This little fn seems to give good results:

                  unsigned int GetRandInt32() {
                  static unsigned x = 0;
                  unsigned n = 5;
                  x = (((4*n+1) * x) + 1231) % INT_MAX;
                  return x;
                  }

                  You can play with the values I have hardcoded (shame on me). There's probably better stuff on the web somewhere. Anyway, the point here is that if you can roll your own rand that gives you values from 0 to INT_MAX you'll probably get a better distribution over the range -INT_MAX to INT_MAX than you will with the current rand(), whose RAND_MAX is 32767 - there's gotta be a loss of precision somewhere there. There may be other considerations - some rands are prone to repeating subseries, some have quirks in that numbers generated alternate between even and odd. Also, there is the concept of a seed - how do we get a fundamentally different sequence out of this? I also wonder if its a hard problem to predict the period given the inputs - I think it might be - though Gauss could probably assure inputs that give the maximum period - I think 257*x + 43981 (mod 65536) recurs after 65536 iterations. Ok - now somebody's going to tell me about a good 5000 page academic text I should go read... sigh... anyway, just thought you might be interested...

                  1 Reply Last reply
                  0
                  • J James Millson

                    Can anybody point me towards a function that's something along the lines of:

                    int32 GetRandomNumberBetween(int32 nLower, int32 nUpper)
                    {
                    // generate random number between upper and lower bounds here...

                    return nTheRandomNumber;
                    

                    }

                    I just can't get it right myself, and I can't find one anywhere on the net or in my books. Yours, James Millson

                    A Offline
                    A Offline
                    Anders Molin
                    wrote on last edited by
                    #9

                    well, I have made this small macro a long time ago:

                    //get a random number between min and max
                    #define GetRandom(min, max) ((rand() % (int)(((max) + 1) - (min))) + (min))

                    You have to call srand() first, if you want to initialize the random generator, something like srand(GetTickCount()); - Anders Money talks, but all mine ever says is "Goodbye!"

                    T 1 Reply Last reply
                    0
                    • A Anders Molin

                      well, I have made this small macro a long time ago:

                      //get a random number between min and max
                      #define GetRandom(min, max) ((rand() % (int)(((max) + 1) - (min))) + (min))

                      You have to call srand() first, if you want to initialize the random generator, something like srand(GetTickCount()); - Anders Money talks, but all mine ever says is "Goodbye!"

                      T Offline
                      T Offline
                      Tim Deveaux
                      wrote on last edited by
                      #10

                      Anders Nice one - but still has problems for very large ranges - maybe I'm going overboard here, but you'll see that it has problems with something like

                      TRACE(_T("GetRandom returns %ld\n"),GetRandom(-INT_MAX, INT_MAX));

                      Not sure if that's the point of this thread, but can you see a way to handle that inline in your macro?

                      A 1 Reply Last reply
                      0
                      • T Tim Deveaux

                        Anders Nice one - but still has problems for very large ranges - maybe I'm going overboard here, but you'll see that it has problems with something like

                        TRACE(_T("GetRandom returns %ld\n"),GetRandom(-INT_MAX, INT_MAX));

                        Not sure if that's the point of this thread, but can you see a way to handle that inline in your macro?

                        A Offline
                        A Offline
                        Anders Molin
                        wrote on last edited by
                        #11

                        Yea, but it works just fine for just about 99% of what people need (I guess) How often do you want a random number larger than a 32 bit int? - Anders Money talks, but all mine ever says is "Goodbye!"

                        1 Reply Last reply
                        0
                        • J James Millson

                          Can anybody point me towards a function that's something along the lines of:

                          int32 GetRandomNumberBetween(int32 nLower, int32 nUpper)
                          {
                          // generate random number between upper and lower bounds here...

                          return nTheRandomNumber;
                          

                          }

                          I just can't get it right myself, and I can't find one anywhere on the net or in my books. Yours, James Millson

                          PJ ArendsP Offline
                          PJ ArendsP Offline
                          PJ Arends
                          wrote on last edited by
                          #12

                          take a look at http://www.math.keio.ac.jp/matumoto/cokus.c for a set of C functions that generate a 32 bit random number. To get a number between nLower and nUpper

                          UINT number = randomMT();
                          number /= (UINT_MAX / (nUpper - nLower));
                          number += nLower;

                          --- Multitasking: Screwing up several things at once.

                          Within you lies the power for good; Use it!

                          1 Reply Last reply
                          0
                          • L Lost User

                            I have written this function and it gives me a random number between [nMin..nMax] int RandBetween(int nMin, int nMax) { int r = (rand() * RAND_MAX + nMin) % nMax; if (r <= nMin) r = nMin+1; else if (r >= nMax) r= nMax-1; return r; } Mh2! :)

                            M Offline
                            M Offline
                            Malcolm McMahon
                            wrote on last edited by
                            #13

                            Shouldn't the nMin be outside the parenthesis?

                            1 Reply Last reply
                            0
                            Reply
                            • Reply as topic
                            Log in to reply
                            • Oldest to Newest
                            • Newest to Oldest
                            • Most Votes


                            • Login

                            • Don't have an account? Register

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • World
                            • Users
                            • Groups