Greetings. Hoping someone here is familiar with this RNG. I couldn't believe how deep the rabbit whole went when I started looking into RNGs. I thought the one that comes with the compiler would be ok, but after some research, it seems that it is inadequate. Anyhow, I stumbled upon this one and was happy to see that it worked after merely copying and pasting into my main.c file in Xcode 9.4.1. unlike about 3-4 others that did not. I have very little experience in C so this might be simple, but I don't know how to manipulate the RN it generates without running into problems. Here's the code:
Code:
// C99 Complementary Multiply With Carry generator
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// CMWC working parts
#define CMWC_CYCLE 4096// as Marsaglia recommends
#define CMWC_C_MAX 809430660// as Marsaglia recommends
struct cmwc_state {
uint32_t Q[CMWC_CYCLE];
uint32_t c; // must be limited with CMWC_C_MAX
unsigned i;
};
// Make 32 bit random number (some systems use 16 bit RAND_MAX [Visual C 2012 uses 15 bits!])
uint32_t rand32(void)
{
uint32_t result = rand();
return result << 16 | rand();
}
// Init the state with seed
void initCMWC(struct cmwc_state *state, unsigned int seed)
{
srand(seed);
for (int i = 0; i < CMWC_CYCLE; i++)
state->Q[i] = rand32();
do
state->c = rand32();
while (state->c >= CMWC_C_MAX);
state->i = CMWC_CYCLE - 1;
}
// CMWC engine
uint32_t randCMWC(structcmwc_state *state) //EDITED parameter *state was missing
{
uint64_tconst a = 18782; // as Marsaglia recommends
uint32_tconst m = 0xfffffffe; // as Marsaglia recommends
uint64_t t;
uint32_t x;
state->i = (state->i + 1) & (CMWC_CYCLE - 1);
t = a * state->Q[state->i] + state->c;
/* Let c = t / 0xfffffff, x = t mod 0xffffffff */
state->c = t >> 32;
x = t + state->c;
if (x < state->c) {
x++;
state->c++;
}
return state->Q[state->i] = m - x;
}
int main()
{
struct cmwc_state cmwc;
unsigned int seed = time(NULL);
initCMWC(&cmwc, seed);
printf("Random CMWC: %u\n", randCMWC(&cmwc));
}
I kinda understand the last line
Code:
printf("Random CMWC: %u\n", randCMWC(&cmwc));
where %u is being used to print the unsigned random integer. But I'm not clear how. I see in the previous line it's being generated with a time seed using then the result is a pointer (I believe), but the program as a whole is way above my pay grade. I have spent many hours trying to get a grip on pointer and memory locations, which I understand, but not with using the parentheses and such. Anyway, the bottom line is that I only really want to generate a series of random numbers between 0 and 107 that are all different. Meaning, that once that number is selected, the RNG can't choose that one again.
After playing with the main() of this program for an extended period of time I have determined that even trying to print another random number comes out different because its being seeded by a different time integer again. Shows you how little c I know. And one last very important thing I would like to add is that I am not beholden to this particular RNG. If anybody know a better one that that I can cut and paste that would be easier for me to understand I am open to the idea.