#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>

uint32_t lcg_rand(uint32_t *a)
{
	*(uint32_t *)a = (uint64_t)*(uint32_t *)a * 279470273 % 4294967291;
	return( *(uint32_t *)a );
}

uint32_t lrand(uint64_t *s){
    // initial value of s must be 2 or higher
    uint64_t hi = *(uint64_t *)s / 41943011;
    uint64_t lo = *(uint64_t *)s % 41943011;
    //uint64_t tmp = *(uint64_t *)s * lo;
    *(uint64_t *)s = *(uint64_t *)s * lo - 2147483647 * hi;

    //if(*(uint64_t *)s < 0) *(uint64_t *)s += 0x7fffffffffffffff;
    return (*(uint64_t *)s & 0xFFFFFFFF00000000) >> 32;
}

uint16_t lrand2(uint32_t *s){
	uint32_t hi = *(uint32_t *)s / 49301;
	uint32_t lo = *(uint32_t *)s % 49301;
	*(uint32_t *)s = *(uint32_t *)s * lo - 655535 * hi;
	return (*(uint32_t *)s & 0xFFFF0000) >> 16;
}


int main(int argc, char **argv){
	struct timeval starttime, endtime, cur;
	uint32_t a;
	uint32_t b = 103;
	uint32_t c;
	uint64_t d = 103;
	double time1;
	uint32_t e[4096];
	uint32_t counts[10];
	(void)memset(counts, '\0', sizeof(uint32_t)*10);
	uint16_t f;

	gettimeofday(&starttime, NULL);
	b = (unsigned int)starttime.tv_usec;
	for(a=1; a<4096; a++){
		//gettimeofday(&starttime, NULL);
		//b = (unsigned int)starttime.tv_usec;
		e[a] = lcg_rand(&b) % 10;
		//printf("%u\n", e[a]);
	}
	for(a=0; a<4096; a++){
		for(d=0; d<10; d++){
			if(e[a] == d)
				counts[d]++;
		}
	}
	for(d=0; d<10; d++){
		printf("%u\n", counts[d]);
	}


//return 0;
    gettimeofday(&starttime, NULL);
    b = (uint32_t)starttime.tv_usec;
	d = (uint64_t)starttime.tv_usec;
	gettimeofday(&starttime, NULL);
	for(a=0; a<2147483647; a++){
		c = lcg_rand(&b);
	}
	gettimeofday(&endtime, NULL);
	time1 = ((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
	printf("%lf\n", time1);
	return 0;
	gettimeofday(&starttime, NULL);
	for(a=0; a<2147483647; a++){
		c = lrand(&d);
	}
	gettimeofday(&endtime, NULL);
	time1 = ((double)(endtime.tv_sec*1000000-starttime.tv_sec*1000000+endtime.tv_usec-starttime.tv_usec))/1000000;
	printf("%lf\n", time1);


	return 0;
}