Skip to content

Instantly share code, notes, and snippets.

@qgp9
Created July 11, 2020 22:48
Show Gist options
  • Save qgp9/6e73c6f55612c9e290feed12e2436e33 to your computer and use it in GitHub Desktop.
Save qgp9/6e73c6f55612c9e290feed12e2436e33 to your computer and use it in GitHub Desktop.
uniqueness test for Linear congruential generator
#include <stdio.h>
#include <time.h>
#define NSUB (1L<<32)
#define NBIT 48
//#define NSUB (1<<4)
//#define NBIT 8
#define COUNT(isub, iseg) (isub*((long)NSUB)+iseg)
#define PRINT_COUNT(msg, count) printf("%s: iSub= %ld\tcount= %ld\tr1= %ld\tr2=%ld\telapse= %f\n", msg, isub, count, r1, r2, elapse)
#define PRINT(msg) PRINT_COUNT(msg, COUNT(isub, iseg))
typedef long index_t;
long random_next(long seed) {
return (seed * 0x5DEECE66DL + 0xBL) & ((1L << NBIT) - 1);
}
clock_t start_timer() {
return clock();
}
clock_t duration_timer(start_clock) {
return ((double) (clock() - start_clock)) / CLOCKS_PER_SEC;
}
int main() {
long seed = 1;
long r1;
long r2;
index_t isub;
index_t iseg;
long count_all = 0;
double elapse = 0;
// first loop to detect loop
isub = 0;
r1 = seed;
r2 = seed;
while (1) {
clock_t start = start_timer();
iseg=0;
while (iseg<NSUB) {
r1 = random_next(r1);
r2 = random_next(random_next(r2));
if (r1 == r2) break;
iseg++;
}
if (r1 == r2) break;
elapse += duration_timer(start);
PRINT("PROC1");
isub++;
}
count_all += COUNT(isub, iseg);
PRINT("FND1");
// if meet point is a seed, which means "complete circlular",
// no need to second loop.
if (r1 == seed) goto done;
// Second loop to find start of loop
isub = 0;
r2 = seed;
while (1) {
clock_t start = start_timer();
iseg=0;
while (iseg<NSUB) {
r1 = random_next(r1);
r2 = random_next(r2);
if (r1 == r2) break;
iseg++;
}
if (r1 == r2) break;
elapse += duration_timer(start);
PRINT("PROC2");
isub++;
}
count_all += COUNT(isub, iseg);
PRINT("FND2");
done:
PRINT_COUNT("DONE", count_all);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment