I would like to go through how rand() and srand() functions are implemented and would like to tweak the code to modify it to my requirements. Where can i find the source code of rand() and srand().
It takes a seed as in input argument, usually like follows:-
double result = srand(time(NULL));
and returns a random number that adheres to the probability and hence expected number of occurrences.
from CodeGuru forums:-
void __cdecl srand (unsigned int seed)
{
#ifdef _MT
_getptd()->_holdrand = (unsigned long)seed;
#else /* _MT */
holdrand = (long)seed;
#endif /* _MT */
}
int __cdecl rand (void)
{
#ifdef _MT
_ptiddata ptd = _getptd();
return( ((ptd->_holdrand = ptd->_holdrand * 214013L + 2531011L) >> 16) &
0x7fff );
#else /* _MT */
return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff);
#endif /* _MT */
}
Hope this helps.
double result = srand(time(NULL));
: why on earth do you have that double result
? srand
doesn't have a return value... –
Saffian _MT
stuff is code to deal with multithreading (the multithreaded runtime library keeps a separate RNG state for each thread); notice that this is why I avoided to post actual library code: it often contains "elements of distraction" not relevant to the real problem. –
Saffian rand
and srand
are usually implemented as a simple LCG, you can easily write your own (it's few lines of code) without looking for the sources of rand
and srand
. Notice that, if you need random numbers for "serious" purposes (e.g. cryptography), there are much better RNGs than LCG.
By the way, the C standard itself includes a sample implementation of rand
and srand
:
static unsigned long int next = 1;
int rand(void) // RAND_MAX assumed to be 32767
{
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}
void srand(unsigned int seed)
{
next = seed;
}
It takes a seed as in input argument, usually like follows:-
double result = srand(time(NULL));
and returns a random number that adheres to the probability and hence expected number of occurrences.
from CodeGuru forums:-
void __cdecl srand (unsigned int seed)
{
#ifdef _MT
_getptd()->_holdrand = (unsigned long)seed;
#else /* _MT */
holdrand = (long)seed;
#endif /* _MT */
}
int __cdecl rand (void)
{
#ifdef _MT
_ptiddata ptd = _getptd();
return( ((ptd->_holdrand = ptd->_holdrand * 214013L + 2531011L) >> 16) &
0x7fff );
#else /* _MT */
return(((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff);
#endif /* _MT */
}
Hope this helps.
holdrand
would grow rapidly and soon cause an overflow. holdrand = holdrand * 214013L + 2531011L
–
Archiepiscopal double result = srand(time(NULL));
: why on earth do you have that double result
? srand
doesn't have a return value... –
Saffian _MT
stuff is code to deal with multithreading (the multithreaded runtime library keeps a separate RNG state for each thread); notice that this is why I avoided to post actual library code: it often contains "elements of distraction" not relevant to the real problem. –
Saffian The glibc one (used by gcc) is the simple formula:
x = 1103515245 * x + 12345
wrapping around at 232, as shown here. You can just set x
as the seed then keep calling a function to evaluate that expression (and update the seed).
But you should be aware the linear congruential generators like this are considered adequate but not ideal.
While the only ideal random number generator would be perfectly random, the Mersenne Twister probably comes closer.
© 2022 - 2024 — McMap. All rights reserved.
holdrand
would grow rapidly and soon cause an overflow.holdrand = holdrand * 214013L + 2531011L
– Archiepiscopal