diff --git a/Makefile b/Makefile index 5592bf2..c12cc16 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,21 @@ TARGETS = pcg32-global-demo pcg32-demo pcg32x2-demo +CFLAGS += -O3 +CFLAGS += -Wall -Wextra -Waggregate-return -Wcast-align -Wcast-qual \ + -Wdisabled-optimization -Wdiv-by-zero -Wendif-labels \ + -Wformat-extra-args -Wformat-nonliteral -Wformat-security \ + -Wformat-y2k -Wimplicit -Wimport -Winit-self -Winline -Winvalid-pch \ + -Wmissing-declarations -Wno-missing-format-attribute \ + -Wmissing-include-dirs -Wmultichar -Wpacked -Wpointer-arith \ + -Wreturn-type -Wsequence-point -Wsign-compare -Wstrict-aliasing \ + -Wstrict-aliasing=2 -Wswitch -Wswitch-default \ + -Wno-unused -Wvariadic-macros -Wwrite-strings -Wc++-compat \ + -Werror=declaration-after-statement \ + -Werror=implicit-function-declaration -Wmissing-prototypes \ + -Werror=nested-externs -Werror=old-style-definition \ + -Werror=strict-prototypes -Werror=missing-braces + all: $(TARGETS) clean: diff --git a/pcg32-demo.c b/pcg32-demo.c index b08df0c..b2703d7 100644 --- a/pcg32-demo.c +++ b/pcg32-demo.c @@ -37,7 +37,7 @@ int main(int argc, char** argv) { - // Read command-line options + /* Read command-line options */ int rounds = 5; bool nondeterministic_seed = false; @@ -54,30 +54,30 @@ int main(int argc, char** argv) rounds = atoi(argv[0]); } - // In this version of the code, we'll use a local rng, rather than the - // global one. + /* In this version of the code, we'll use a local rng, rather than the + global one. */ pcg32_random_t rng; - // You should *always* seed the RNG. The usual time to do it is the - // point in time when you create RNG (typically at the beginning of the - // program). - // - // pcg32_srandom_r takes two 64-bit constants (the initial state, and the - // rng sequence selector; rngs with different sequence selectors will - // *never* have random sequences that coincide, at all) - the code below - // shows three possible ways to do so. + /* You should *always* seed the RNG. The usual time to do it is the + point in time when you create RNG (typically at the beginning of the + program). */ + + /* pcg32_srandom_r takes two 64-bit constants (the initial state, and the + rng sequence selector; rngs with different sequence selectors will + *never* have random sequences that coincide, at all) - the code below + shows three possible ways to do so. */ if (nondeterministic_seed) { - // Seed with external entropy -- the time and some program addresses - // (which will actually be somewhat random on most modern systems). - // A better solution, entropy_getbytes, using /dev/random, is provided - // in the full library. + /* Seed with external entropy -- the time and some program addresses + (which will actually be somewhat random on most modern systems) + A better solution, entropy_getbytes, using /dev/random, is provided + in the full library. */ pcg32_srandom_r(&rng, time(NULL) ^ (intptr_t)&printf, (intptr_t)&rounds); } else { - // Seed with a fixed constant + /* Seed with a fixed constant */ pcg32_srandom_r(&rng, 42u, 54u); } diff --git a/pcg32-global-demo.c b/pcg32-global-demo.c index 3714b47..a11067c 100644 --- a/pcg32-global-demo.c +++ b/pcg32-global-demo.c @@ -37,7 +37,7 @@ int main(int argc, char** argv) { - // Read command-line options + /* Read command-line options */ int rounds = 5; bool nondeterministic_seed = false; @@ -54,17 +54,17 @@ int main(int argc, char** argv) rounds = atoi(argv[0]); } - // In this version of the code, we'll use the global rng, rather than a - // local one. + /* In this version of the code, we'll use the global rng, rather than a + local one. */ - // You should *always* seed the RNG. The usual time to do it is the - // point in time when you create RNG (typically at the beginning of the - // program). - // - // pcg32_srandom_r takes two 64-bit constants (the initial state, and the - // rng sequence selector; rngs with different sequence selectors will - // *never* have random sequences that coincide, at all) - the code below - // shows three possible ways to do so. + /* You should *always* seed the RNG. The usual time to do it is the + point in time when you create RNG (typically at the beginning of the + program). */ + + /* pcg32_srandom_r takes two 64-bit constants (the initial state, and the + rng sequence selector; rngs with different sequence selectors will + *never* have random sequences that coincide, at all) - the code below + shows three possible ways to do so. */ if (nondeterministic_seed) { // Seed with external entropy -- the time and some program addresses @@ -74,7 +74,7 @@ int main(int argc, char** argv) pcg32_srandom(time(NULL) ^ (intptr_t)&printf, (intptr_t)&rounds); } else { - // Seed with a fixed constant + /* Seed with a fixed constant */ pcg32_srandom(42u, 54u); } diff --git a/pcg32x2-demo.c b/pcg32x2-demo.c index f2d820f..fb5afa2 100644 --- a/pcg32x2-demo.c +++ b/pcg32x2-demo.c @@ -60,7 +60,7 @@ void pcg32x2_srandom_r(pcg32x2_random_t* rng, uint64_t seed1, uint64_t seed2, uint64_t seq1, uint64_t seq2) { uint64_t mask = ~0ull >> 1; - // The stream for each of the two generators *must* be distinct + /* The stream for each of the two generators *must* be distinct */ if ((seq1 & mask) == (seq2 & mask)) seq2 = ~seq2; pcg32_srandom_r(rng->gen, seed1, seq1); @@ -89,7 +89,7 @@ int dummy_global; int main(int argc, char** argv) { - // Read command-line options + /* Read command-line options */ int rounds = 5; bool nondeterministic_seed = false; @@ -111,27 +111,27 @@ int main(int argc, char** argv) pcg32x2_random_t rng; - // You should *always* seed the RNG. The usual time to do it is the - // point in time when you create RNG (typically at the beginning of the - // program). - // - // pcg32x2_srandom_r takes four 64-bit constants (the initial state, and - // the rng sequence selector; rngs with different sequence selectors will - // *never* have random sequences that coincide, at all) - the code below - // shows three possible ways to do so. + /* You should *always* seed the RNG. The usual time to do it is the + point in time when you create RNG (typically at the beginning of the + program). */ + + /* pcg32x2_srandom_r takes four 64-bit constants (the initial state, and + the rng sequence selector; rngs with different sequence selectors will + *never* have random sequences that coincide, at all) - the code below + shows three possible ways to do so. */ if (nondeterministic_seed) { - // Seed with external entropy -- the time and some program addresses - // (which will actually be somewhat random on most modern systems). - // A better solution, entropy_getbytes, using /dev/random, is provided - // in the full library. + /* Seed with external entropy -- the time and some program addresses + (which will actually be somewhat random on most modern systems). + A better solution, entropy_getbytes, using /dev/random, is provided + in the full library. */ pcg32x2_srandom_r(&rng, time(NULL) ^ (intptr_t)&printf, ~time(NULL) ^ (intptr_t)&pcg32_random_r, (intptr_t)&rounds, (intptr_t)&dummy_global); } else { - // Seed with a fixed constant + /* Seed with a fixed constant */ pcg32x2_srandom_r(&rng, 42u, 42u, 54u, 54u); } diff --git a/pcg_basic.c b/pcg_basic.c index 8c2fd0d..c1c9a2f 100644 --- a/pcg_basic.c +++ b/pcg_basic.c @@ -30,14 +30,14 @@ #include "pcg_basic.h" -// state for global RNGs +/* state for global RNGs */ static pcg32_random_t pcg32_global = PCG32_INITIALIZER; -// pcg32_srandom(initstate, initseq) -// pcg32_srandom_r(rng, initstate, initseq): -// Seed the rng. Specified in two parts, state initializer and a -// sequence selection constant (a.k.a. stream id) +/* pcg32_srandom(initstate, initseq) + * pcg32_srandom_r(rng, initstate, initseq): + * Seed the rng. Specified in two parts, state initializer and a + * sequence selection constant (a.k.a. stream id) */ void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initstate, uint64_t initseq) { @@ -53,9 +53,9 @@ void pcg32_srandom(uint64_t seed, uint64_t seq) pcg32_srandom_r(&pcg32_global, seed, seq); } -// pcg32_random() -// pcg32_random_r(rng) -// Generate a uniformly distributed 32-bit random number +/* pcg32_random() + * pcg32_random_r(rng) + * Generate a uniformly distributed 32-bit random number */ uint32_t pcg32_random_r(pcg32_random_t* rng) { @@ -66,41 +66,41 @@ uint32_t pcg32_random_r(pcg32_random_t* rng) return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); } -uint32_t pcg32_random() +uint32_t pcg32_random(void) { return pcg32_random_r(&pcg32_global); } -// pcg32_boundedrand(bound): -// pcg32_boundedrand_r(rng, bound): -// Generate a uniformly distributed number, r, where 0 <= r < bound +/* pcg32_boundedrand(bound): + * pcg32_boundedrand_r(rng, bound): + * Generate a uniformly distributed number, r, where 0 <= r < bound */ uint32_t pcg32_boundedrand_r(pcg32_random_t* rng, uint32_t bound) { - // To avoid bias, we need to make the range of the RNG a multiple of - // bound, which we do by dropping output less than a threshold. - // A naive scheme to calculate the threshold would be to do - // - // uint32_t threshold = 0x100000000ull % bound; - // - // but 64-bit div/mod is slower than 32-bit div/mod (especially on - // 32-bit platforms). In essence, we do - // - // uint32_t threshold = (0x100000000ull-bound) % bound; - // - // because this version will calculate the same modulus, but the LHS - // value is less than 2^32. + /* To avoid bias, we need to make the range of the RNG a multiple of + * bound, which we do by dropping output less than a threshold. + * A naive scheme to calculate the threshold would be to do + * + * uint32_t threshold = 0x100000000ull % bound; + * + * but 64-bit div/mod is slower than 32-bit div/mod (especially on + * 32-bit platforms). In essence, we do + * + * uint32_t threshold = (0x100000000ull-bound) % bound; + * + * because this version will calculate the same modulus, but the LHS + * value is less than 2^32. */ uint32_t threshold = -bound % bound; - // Uniformity guarantees that this loop will terminate. In practice, it - // should usually terminate quickly; on average (assuming all bounds are - // equally likely), 82.25% of the time, we can expect it to require just - // one iteration. In the worst case, someone passes a bound of 2^31 + 1 - // (i.e., 2147483649), which invalidates almost 50% of the range. In - // practice, bounds are typically small and only a tiny amount of the range - // is eliminated. + /* Uniformity guarantees that this loop will terminate. In practice, it + * should usually terminate quickly; on average (assuming all bounds are + * equally likely), 82.25% of the time, we can expect it to require just + * one iteration. In the worst case, someone passes a bound of 2^31 + 1 + * (i.e., 2147483649), which invalidates almost 50% of the range. In + * practice, bounds are typically small and only a tiny amount of the range + * is eliminated. */ for (;;) { uint32_t r = pcg32_random_r(rng); if (r >= threshold) diff --git a/pcg_basic.h b/pcg_basic.h index e2b526a..23ef23e 100644 --- a/pcg_basic.h +++ b/pcg_basic.h @@ -37,36 +37,36 @@ extern "C" { #endif -struct pcg_state_setseq_64 { // Internals are *Private*. - uint64_t state; // RNG state. All values are possible. - uint64_t inc; // Controls which RNG sequence (stream) is - // selected. Must *always* be odd. +struct pcg_state_setseq_64 { /* Internals are *Private*. */ + uint64_t state; /* RNG state. All values are possible. */ + uint64_t inc; /* Controls which RNG sequence (stream) is */ + /* selected. Must *always* be odd. */ }; typedef struct pcg_state_setseq_64 pcg32_random_t; -// If you *must* statically initialize it, here's one. +/* If you *must* statically initialize it, here's one. */ #define PCG32_INITIALIZER { 0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL } -// pcg32_srandom(initstate, initseq) -// pcg32_srandom_r(rng, initstate, initseq): -// Seed the rng. Specified in two parts, state initializer and a -// sequence selection constant (a.k.a. stream id) +/* pcg32_srandom(initstate, initseq) + * pcg32_srandom_r(rng, initstate, initseq): + * Seed the rng. Specified in two parts, state initializer and a + * sequence selection constant (a.k.a. stream id) */ void pcg32_srandom(uint64_t initstate, uint64_t initseq); void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initstate, uint64_t initseq); -// pcg32_random() -// pcg32_random_r(rng) -// Generate a uniformly distributed 32-bit random number +/* pcg32_random() + * pcg32_random_r(rng): + * Generate a uniformly distributed 32-bit random number */ uint32_t pcg32_random(void); uint32_t pcg32_random_r(pcg32_random_t* rng); -// pcg32_boundedrand(bound): -// pcg32_boundedrand_r(rng, bound): -// Generate a uniformly distributed number, r, where 0 <= r < bound +/* pcg32_boundedrand(bound) + * pcg32_boundedrand_r(rng, bound): + * Generate a uniformly distributed number, r, where 0 <= r < bound */ uint32_t pcg32_boundedrand(uint32_t bound); uint32_t pcg32_boundedrand_r(pcg32_random_t* rng, uint32_t bound); @@ -75,4 +75,4 @@ uint32_t pcg32_boundedrand_r(pcg32_random_t* rng, uint32_t bound); } #endif -#endif // PCG_BASIC_H_INCLUDED +#endif /* PCG_BASIC_H_INCLUDED */