Sign in to follow this  
wyrd

Anyone have an efficient rand() macro?

Recommended Posts


// Essentially we're just picking a value between 0 and 1 and then
// multiplying that by the difference between the high and low, then we add
// it to the low variable.
#define FRAND(nLow, nHigh) ( ( (1.0f / ( (rand() % 100) + 1) ) * ((nHigh) - (nLow ) ) ) + (nLow) )

// This is the same deal, but for integers
#define IRAND(low,high) (rand() % ( (high) - (low) + 1) + (low) )





The rand() % 100 just means that the floats will have a precision of two decimal points. You can make this higher or lower depending on what you want.


[EDIT] I dunno if this is efficient enough, but I can't think of a more accurate way to do it.

Share this post


Link to post
Share on other sites
If actually using rand(), I'd suggest
float Random(float Min, float Max)
{
return ((float)rand() / (float)RAND_MAX) * (Max - Min) + Min;
}
As for efficiency, I dunno. There's an int-to-float cast, a float multiplication, a float division, a float addition, and a float subtraction (the whole works, I suppose).

Or many people are directed towards the Mersenne Twister, which I still have yet to try out. It appears to have some double functions which are likely to be sufficiently fast.

Share this post


Link to post
Share on other sites
Quote:
Original post by moeron
*** Source Snippet Removed ***

The rand() % 100 just means that the floats will have a precision of two decimal points. You can make this higher or lower depending on what you want.


[EDIT] I dunno if this is efficient enough, but I can't think of a more accurate way to do it.


Err, sorry, but that snippit will have really really horrible distribution, unless I'm missing something. The problem is that:

1 / rand() does NOT have anywhere near uniform distribution. There's only 1 potential return that rand() can give to have a value of over 0.5 (that is, 1). There's then another return that it can give for 0.5 (that is, 2). For everything else (RAND_MAX-2) it will be between 0 and 0.5. This means the distribution will look like this:

0.0 0.25 0.5 0.75 1.0
|-------|-------|-------|-------|
... . . . .


As others have suggested, ((float)rand())/RAND_MAX is the way to go. This will give as uniform distribution as rand() will give. There's no need to add modulo operators into the mix as they will only slow the code down, decrease accuracy, and provide no benifit (by limiting the range - since that's easily doable by scaling in floating point).

Share this post


Link to post
Share on other sites
Quote:
Original post by MaulingMonkey
Quote:
Original post by moeron
*** Source Snippet Removed ***

The rand() % 100 just means that the floats will have a precision of two decimal points. You can make this higher or lower depending on what you want.


[EDIT] I dunno if this is efficient enough, but I can't think of a more accurate way to do it.


Err, sorry, but that snippit will have really really horrible distribution, unless I'm missing something. The problem is that:

1 / rand() does NOT have anywhere near uniform distribution. There's only 1 potential return that rand() can give to have a value of over 0.5 (that is, 1). There's then another return that it can give for 0.5 (that is, 2). For everything else (RAND_MAX-2) it will be between 0 and 0.5. This means the distribution will look like this:


0.0 0.25 0.5 0.75 1.0
|-------|-------|-------|-------|
... . . . .


As others have suggested, ((float)rand())/RAND_MAX is the way to go. This will give as uniform distribution as rand() will give. There's no need to add modulo operators into the mix as they will only slow the code down, decrease accuracy, and provide no benifit (by limiting the range - since that's easily doable by scaling in floating point).


Thanks, I can't believe I never noticed that, thanks for pointing that out to me. It never mattered for what I was using it for, but I will definately update that for my future applications.

Share this post


Link to post
Share on other sites
Quote:
Original post by moeron
Quote:
Original post by MaulingMonkey
Quote:
Original post by moeron
*** Source Snippet Removed ***

The rand() % 100 just means that the floats will have a precision of two decimal points. You can make this higher or lower depending on what you want.


[EDIT] I dunno if this is efficient enough, but I can't think of a more accurate way to do it.


Err, sorry, but that snippit will have really really horrible distribution, unless I'm missing something. The problem is that:

1 / rand() does NOT have anywhere near uniform distribution. There's only 1 potential return that rand() can give to have a value of over 0.5 (that is, 1). There's then another return that it can give for 0.5 (that is, 2). For everything else (RAND_MAX-2) it will be between 0 and 0.5. This means the distribution will look like this:


0.0 0.25 0.5 0.75 1.0
|-------|-------|-------|-------|
... . . . .


As others have suggested, ((float)rand())/RAND_MAX is the way to go. This will give as uniform distribution as rand() will give. There's no need to add modulo operators into the mix as they will only slow the code down, decrease accuracy, and provide no benifit (by limiting the range - since that's easily doable by scaling in floating point).


Thanks, I can't believe I never noticed that, thanks for pointing that out to me. It never mattered for what I was using it for, but I will definately update that for my future applications.


No problem. I used to be "the math whiz" at school so the shape of 1/x sort of immediately sticks out in my mind :). Of course, the last math class I took I flunked, but that was because I was quite distracted... ^_^;;. Actually, I take that back, IIRC I retook it and got a C (again while distracted). Bleh.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this