Skip to content

Questiable LCG #1

Description

@Wolf-SO

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);
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions