|
1. Random Numbers in a Range
|
|
Tue Jul 27, 2004 [12:36 AM]
|
nephos
Email not supplied
member since: Jan 14, 2001
|
Reply
|
|
Here's something from the ROT codebase, used to generate random numbers. I'm sure it's probably in almost all Diku-derivatives.
/* * Generate a random number. */ int number_range( int from, int to ) { int power; int number;
if (from == 0 && to == 0) { return 0; }
if ( ( to = to - from + 1 ) <= 1 ) { return from; }
for ( power = 2; power < to; power <<= 1 ) { ; }
while ( ( number = number_mm() & (power -1 ) ) >= to ) { ; }
return from + number; }
long number_mm( void ) { #if defined (OLD_RAND) int *piState; int iState1; int iState2; int iRand; piState = &rgiState[2]; iState1 = piState[-2]; iState2 = piState[-1]; iRand = (piState[iState1] + piState[iState2]) & ((1 << 30) - 1); piState[iState1] = iRand; if ( ++iState1 == 55 ) { iState1 = 0; } if ( ++iState2 == 55 ) { iState2 = 0; } piState[-2] = iState1; piState[-1] = iState2; return iRand >> 6; #else return random() >> 6; #endif }
Now, I coded a different function with the same affect as number_range(), I called it rand_range(), though this isn't related to Diku at all, as it's on my own codebase, but anyway, I made it work as such:
// Returns a random number between the minimum and maximum (inclusive) // using the modulus operator. Ingenius maybe. int rand_range(int min, int max) { int diff; int x = rand();
if (max <= min) { return min; } diff = max - min; diff++; x = x % diff; return (max - x); }
Could there be any compatibility problems with just calling rand() as such. If not, it seems as though this code would be a lot more efficient than that in Diku. I didn't put much error-checking into it, just that "if (max <= min)". Anyway, does this all look safe? It works fine so far, but that's just on my compiler.
(Comment added by nephos on Tue Jul 27 16:11:30 2004)
Thanks for the help everyone. From all that's been said, it seems the function is fine and would work on most non-dinosaur compilers, so I'll keep it as is.
|
|
|
|
|
2. RE: Random Numbers in a Range
|
|
Tue Jul 27, 2004 [6:05 AM]
|
KaVir
Email not supplied
member since: Aug 19, 1999
|
In Reply To
Reply
|
> Could there be any compatibility problems with just > calling rand() as such. If not, it seems as though this > code would be a lot more efficient than that in Diku. The random number generator comes from Merc, and is actually explained in the comments further down: /*
* I've gotten too many bad reports on OS-supplied random number generators.
* This is the Mitchell-Moore algorithm from Knuth Volume II.
* Best to leave the constants alone unless you've read Knuth.
* -- Furey
*/
|
|
|
|
|
3. RE: Random Numbers in a Range
|
|
Tue Jul 27, 2004 [6:07 AM]
|
Fredrik
Email not supplied
member since: Feb 15, 2000
|
In Reply To
Reply
|
|
I don't see anything wrong with it... C99 specifies (see e.g. http://www.dinkumware.com/manuals/reader.aspx?b=c/&h=stdlib.html#rand) that rand should return a positive signed integer so I think you're safe on any compliant compiler.
|
|
|
|
|
4. RE: Random Numbers in a Range
|
|
Tue Jul 27, 2004 [9:52 AM]
|
Razzer_9
Email not supplied
member since: Mar 5, 2001
|
In Reply To
Reply
|
|
Could there be any compatibility problems with just calling rand() as such.
No. rand() is a standard C and C++ function. It should be portable to any system to which you would port your MUD.
If not, it seems as though this code would be a lot more efficient than that in Diku.
Maybe. Maybe not. rand() can be implemented differently from system to system. However, most rand() implementations use a very simple and fast algorithm, so your function could possibly be more efficient.
|
|
|
|
|
5. RE: Random Numbers in a Range
|
|
Tue Jul 27, 2004 [12:53 PM]
|
Drey
Email not supplied
member since: Mar 19, 2000
|
In Reply To
Reply
|
|
This would seem to no-longer be an issue if you're working with glibc at least. From "man random":
"The versions of rand() and srand() in the Linux C Library use the same random number generator as random() and srandom(), so the lower-order bits should be as random as the higher-order bits. However, on older rand() implementations, the lower-order bits are much less random than the higher-order bits."
|
|
|
|
|
6. RE: Random Numbers in a Range
|
|
Tue Jul 27, 2004 [1:12 PM]
|
Razzer_9
Email not supplied
member since: Mar 5, 2001
|
In Reply To
Reply
|
Well, at the moment, I'm on my Windows side so I only have Cygwin to work with at the moment, but here is the results of my test: Test.c #include #include
int main( void ) { srand(0); int r = rand(); printf("%d\n",r); srandom(0); r = random(); printf("%d\n",r); return 0; }
Dan@win-fedora ~ $ gcc -o test test.c Dan@win-fedora ~ $ ./test 0 826837439 Now, I have never used random() and srandom() before, so please correct me if I made a bad assumption about the seed passed to srandom(). (Comment added by Razzer_9 on Tue Jul 27 14:12:58 2004)Bleh. Sorry. I copied and pasted the code so I forgot to change the headers a bit. Those, of course, should be: #include <stdlib.h> #include <stdio.h>
|
|
|
|
|
7. RE: Random Numbers in a Range
|
|
Tue Jul 27, 2004 [2:24 PM]
|
Drey
Email not supplied
member since: Mar 19, 2000
|
In Reply To
Reply
|
|
That didn't compile for gcc 2.95 because the 'int r' declaration needs to occur before the 'srand(0)' call. Once I made that change and it compiled, I ran it and got:
1804289383 1804289383
|
|
|
|
|
8. RE: Random Numbers in a Range
|
|
Tue Jul 27, 2004 [3:02 PM]
|
Razzer_9
Email not supplied
member since: Mar 5, 2001
|
In Reply To
Reply
|
|
Opps. I keep forgetting to not program like I was using C++ or C99* :). However, I think the test shows that rand() is useful for random-numbers where the randomness of the numbers isn't very critical (like in a small MUD).
[*] Yes, I know I wasn't compiling in C99 mode with my compiler at the time.
|
|
|
|
|