I really appreciate this API: _meta_inline int32 lcgRandom(_Inout_ uint32* state) as it is reentrant.
But I found the range of outputs generated by the function suspicious.
The classic implementation seems to be this:
// Source - https://stackoverflow.com/q/8569113
// Posted by Adam Stelmaszczyk, modified by community. See post 'Timeline' for change history
// Retrieved 2026-05-21, License - CC BY-SA 3.0
static unsigned long int next = 1;
int rand(void) /* RAND_MAX assumed to be 32767. */
{
next = next * 1103515245 + 12345;
return (unsigned)(next/65536) % 32768;
}
And a discussion of another “classic” approach that is close to lcgRandom is this:
static unsigned int next = 0;
void srand(unsigned int seed) {
next = seed;
}
/* RAND_MAX assumed to be 32767 */
int rand(void) {
next = next * 1103515245 + 12345;
return next % 32768;
}
Which is discussed in Computer Security Dawn Song (CS 161, Fall 2008, Notes 4) on page 2. I'd expect that a modulus of 2<sup>31</sup> would result in a comparable biased output. I mean, does it really change the low entropy in the lower bits?
Or to put it another way: In what ways is your implementation better than the following one?
_meta_inline int32 lcgRandom(_Inout_ uint32* state)
{
return ((*state = *state * 1103515245 + 12345) & 0x7fffffff);
}
I really appreciate this API:
_meta_inline int32 lcgRandom(_Inout_ uint32* state)as it is reentrant.But I found the range of outputs generated by the function suspicious.
The classic implementation seems to be this:
And a discussion of another “classic” approach that is close to
lcgRandomis this:Which is discussed in Computer Security Dawn Song (CS 161, Fall 2008, Notes 4) on page 2. I'd expect that a modulus of
2<sup>31</sup>would result in a comparable biased output. I mean, does it really change the low entropy in the lower bits?Or to put it another way: In what ways is your implementation better than the following one?