Jump to content
  • Advertisement
Sign in to follow this  
wyrd

Anyone have an efficient rand() macro?

This topic is 4900 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Advertisement
i think this should work ... but i'm not exactly sure what you are looking for.

EDIT: this one works ...

#define RAND(a,b) (float)((float)(rand()%a)/b)

Share this post


Link to post
Share on other sites

// 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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!