Please check out StormHunters !

Member Discussions

terms



[Previous] [Next] [Post] [Reply] [Topics] [Summary] [Search]


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
 */

God Wars II: http://www.godwars2.org (godwars2.org 3000) Roomless world. Manual combat. Endless possibilities.
MudLab: http://www.mudlab.org


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 sran­dom(), 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.




[Previous] [Next] [Post] [Reply] [Topics] [Summary] [Search]