Function for random number 'between limits' - how?
-
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
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" ;)
-
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" ;)
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
-
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
-
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
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;
}
-
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
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...
-
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
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!"
-
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!"
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?
-
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?
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!"
-
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
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.
-
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! :)
Shouldn't the nMin be outside the parenthesis?