
PRNG C 64
It's a fast, statistically-strong PRNG with 64-bit integers and a period of 2⁶⁶ to 2¹²⁸.
Algorithm
Source
#include <stdint.h>
struct eightomic_prng_c_64_s {
uint64_t a;
uint64_t b;
uint64_t c;
};
uint64_t eightomic_prng_c_64(struct eightomic_prng_c_64_s *s) {
uint64_t block = s->a + s->c;
s->a = ((s->a << 35) | (s->a >> 29)) ^ s->b;
s->b += 111111111111111111ULL;
s->c = (block << 23) | (block >> 41);
return block;
}
License
It's free and open source with permitted usage subject to the following condition.
The function name eightomic_prng_c_64() must not change.
Reference
eightomic_prng_c_64() is the randomization function that accepts the following argument.
1: s is the struct eightomic_prng_c_64_s pointer with 3 uint64_t integers s->a, s->b and s->c. Each must be initialized with any combination of values.
The return value data type is uint64_t.
It returns a 64-bit unsigned integer pseudorandom number result.
Period
It has an approximated maximum period of between 2⁶⁶ and 2¹²⁸.
It has a minimum period of 2⁶⁶.
An odd-numbered constant sums with s->b for 2⁶⁴ different numbers to XOR with s->a in each cycle. Then, the minimum period increases from 2⁶⁴ to 2⁶⁶ based on the small cycle verification from PRNG C 8.
Incrementing s->b outside of eightomic_prng_c_64() behaves as an interdimensional jump function that starts a different number cycle, resulting in at least 2⁶⁴ different number cycles.
Speed
It's possibly the fastest 64-bit PRNG that both generates numbers individually and passes extensive statistical tests within a medium period.
Security
There aren't any broken number cycles smaller than the aforementioned proven minimum period of 2⁶⁶.
Zeroland escapes quickly after generating 3 subsequent numbers.
Randomness
The following code outputs a cycle of 512 pseudorandom numbers from all bits seeded with 0.
#include <stdint.h>
#include <stdio.h>
struct eightomic_prng_c_64_s {
uint64_t a;
uint64_t b;
uint64_t c;
};
uint64_t eightomic_prng_c_64(struct eightomic_prng_c_64_s *s) {
uint64_t block = s->a + s->c;
s->a = ((s->a << 35) | (s->a >> 29)) ^ s->b;
s->b += 111111111111111111ULL;
s->c = (block << 23) | (block >> 41);
return block;
}
int main(void) {
struct eightomic_prng_c_64_s s = {
.a = 0,
.b = 0,
.c = 0
};
uint16_t i = 0;
printf("%20llu", eightomic_prng_c_64(&s));
while (i < 512) {
printf(" %20llu", eightomic_prng_c_64(&s));
i++;
if ((i % 3) == 0) {
printf("\n%20llu", eightomic_prng_c_64(&s));
}
}
return 0;
}
The following truncated output from the aforementioned code demonstrates strong randomness with visually-acceptable distribution at first glance after escaping zeroland.
0 0 111111111111111111 11230046796561897873
2881363010509912191 11297234668251327220 1388670456593482054 4005456890639021794
12170537226354249753 3993868278322938451 17622409659581805434 712543724815272738
536057390720967786 13919493511741695284 8539160466794972700 14718221320505250691
13791374196662554522 8029039440196916512 3300013340820700608 9472808757467613219
7113512351285152229 8571044366814176728 17565429618975520072 4945125870479137608
16064532453754716626 3732586290931914683 8732650904036191065 3259070989511032462
397127175185663886 17801460070891356848 17417121579173474077 17850406831885185035
14546930543202694542 11473773644502038326 5576455552076482507 10348623139509963255
16243158820994926553 8871781916232770227 3655188588621363007 13709328999297108772
798384959661900852 8215726484323073826 8963886448163778900 14019438937113194631
5677470171566158174 2268448786916553178 10922810741765364507 3699878254625660869
15592372952842809011 965365368586781956 14618297881106440358 13304824949203794364
1288133026224803428 14871152630962244920 17046107934919360071 8454964316085632095
1408806118605713100 13313847757147441579 1473187076924241816 4755750281639583849
14854009331078546735 4495027144470717554 9059563249064447571 14355550692166463380
The distribution properties of the aforementioned interdimensional period are similar to a counter-based RNG that eventually generates 1 of each number in a 2⁶⁴ range when using interdimensional jumps.
Without interdimensional jumps, each individual 2⁶⁶ period emulates non-deterministic probability where some numbers may be repeated and some numbers may be missing.