#include <stdio.h>
#include <stdint.h>

typedef struct {
	uint32_t low;
	uint32_t high;
} twoint;

typedef struct {
	twoint a;
	twoint b;
} twostate;

uint64_t simple_lcg(uint64_t a, uint64_t c, uint64_t m, uint64_t x) {
	return ((a * x) + c) % m;
}

uint64_t twoint_to_long(twoint num) {
	void* something = (void*)&num;
	uint64_t* result = (uint64_t*)something;
	return *result;
}

twoint long_to_twoint(uint64_t num) {
	void* something = (void*)&num;
	twoint* result = (twoint*)something;
	return *result;
}

uint64_t badRand(twostate* state) {
	twoint num = { state->a.low, state->b.low };
	return twoint_to_long(num);
}

uint64_t goodRand(twostate* state) {
	twoint num = { state->a.high, state->b.high };
	return twoint_to_long(num);
}

void lcg(twostate* state) {
	#define ELCG(x) simple_lcg(0xABAD1DEA, 0xDEADBEEF, UINT64_MAX, x)
	uint64_t na = ELCG(twoint_to_long(state->a));
	uint64_t nb = ELCG(twoint_to_long(state->b));

	state->a = long_to_twoint(na);
	state->b = long_to_twoint(nb);
}

int main(int argc, char *argv[])
{
	twoint a = { 1, 2 };
	twoint b = { 3, 4 };
	twostate state = { a, b };

	for(int i = 0; i < 10; i++) {
		lcg(&state);
		printf("[%d]\n", i + 1);
		printf("Good random, use it: %llu \n", goodRand(&state));
		printf("Bad random, don't use it: %llu \n", badRand(&state));
	}
    return 0;
}
