Created
July 11, 2020 22:48
-
-
Save qgp9/6e73c6f55612c9e290feed12e2436e33 to your computer and use it in GitHub Desktop.
uniqueness test for Linear congruential generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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