# 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.

## Recommended Posts

Does anyone have a highly efficient rand() macro? Especially for FLOAT values.

##### Share on other sites
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 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 on other sites
are you trying to predict the future? :)

##### 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 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 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 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.

1. 1
Rutin
24
2. 2
3. 3
JoeJ
20
4. 4
5. 5

• 9
• 46
• 41
• 23
• 13
• ### Forum Statistics

• Total Topics
631746
• Total Posts
3002021
×