WSP-PRNG-16: The Fastest 16-Bit PRNG With Good Quality

William Stafford Parsons developed a 16-bit pseudorandom number generator algorithm as a substantial improvement to standard library rand() functions, PCG16 and Xorshift16 "798".

Library

Source

#include <stdint.h> struct wsp_prng_16_s { uint32_t increment; uint32_t increment_offset; }; uint16_t wsp_prng_16_randomize(struct wsp_prng_16_s *s) { s->increment_offset = ((s->increment_offset << 13) | (s->increment_offset >> 19)) ^ s->increment; s->increment += 1111111; return s->increment_offset; }

Reference

wsp_prng_16_randomize() is the randomization function that accepts the following argument.

s is a struct wsp_prng_16_s pointer with 2 32-bit unsigned integers s->increment and s->increment_offset, each initialized with any seed values.

The return value data type is uint16_t.

It returns the 16-bit unsigned integer pseudorandom number result.

Requirements

C compiler with C99 (ISO/IEC 9899:1999) standard compatibility.

Explanation

WSP-PRNG-16 is designed to use as an improvement to PRNGs that generate a large amount of small numbers.

It's portable for both 32-bit and 64-bit systems.

It meets strict compliance, portability and code security requirements, although it's a PRNG that isn't suitable for cryptographic purposes.

It doesn't use modulus, multiplication or division arithmetic operations.

16-bit deterministic randomness is generated with a 64-bit state.

By default, the period guarantees a smallest full cycle of 2³² numbers.

32 bits of state in s->increment are summed with 1111111 after each random number generation result and mixed in with the bit shuffling sequence.

This linear increment eliminates the probability of broken infinite cycles when combined with increment_offset and makes it trivial to add an occasional increment externally for estimated, randomized jumps.

Furthermore, when all state bits are 0, the next pseudorandom number escapes zeroland quickly, making it impossible to have a broken state with any combination of numbers.

It passes stdin16 PractRand tests up to 32 MB or 4 million randomized numbers.

Compared to rand() in a local C99 implementation, it's 1000% faster with better statistical quality. rand() passes PractRand tests up to 512 KB or 256,000 randomized numbers, which is 7% of the quality random numbers WSP-PRNG-16 generates.

Compared to PCG16, it's at least 150% faster. PCG16 passes PractRand tests up to 250 million randomized 16-bit numbers and may be a reasonable alternative in some applications where statistical randomness evidence is critical.

Compared to all Xoroshiro and Xorshift algorithms, including Xorshift16 "798", it's 45% to 65% faster. Xorshift16 "798" passes PractRand tests up to 64 KB or 32,000 randomized numbers, which is less than 1% of the quality random numbers WSP-PRNG-16 generates.

Furthermore, some of these PRNGs are vulnerable to several confirmed broken cycles when seeded with specific values, including 0.

Compared to the lower 16 bits of WSP-PRNG-32, it's 30% faster.

All speed tests were performed locally by generating 1 billion numbers on a Pixelbook Go M3 using Debian.

Games

ContrivityContrivity Icon

Contrivity

Spawn into the hostile quantum laboratory and destroy oscillations.