/**
 * random number generator
 * rand(),srand(),time()
 * summary:
 * 1. 如果seed确定,那么产生的随机数(或随机数序列)也是确定的;默认seed值为1;
 * 2. 见①
 * 3. 产生一定范围内的随机数,见test-05
 * 4. 局限:随机数不会超过RAND_MAX
 * 5. 是否等概率:test-07,code-02
 * 6. 易犯的错误:test-06
 *
 * 参考文章:
 * http://c.chinaitlab.com/basic/841799.html, “伪随机数”的产生原理
 * http://baike.baidu.com/view/876758.htm, 不完全正确
 * http://www.cplusplus.com/reference/clibrary/cstdlib/rand/, rand()
 * http://www.cplusplus.com/reference/clibrary/cstdlib/srand/, srand()
 * http://www.cplusplus.com/reference/clibrary/ctime/time/, time()
 * 
 * Platform: Windows
 * Compiler: gcc(CodeBlocks), VC++ 2008
 */
// code-01
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
    // test-01: default seed(the default seed is 1)
    printf("%d\n", rand());		// 41
    printf("%d\n", rand());		// 18467
    printf("%d\n", rand());		// 6334
    							// ①3次结果不一样;但test-03和test-01一样
    printf("--------------------\n");

    // test-02: set seed to 2
    srand(2);
    printf("%d\n", rand());
    printf("%d\n", rand());
    printf("%d\n", rand());
    printf("--------------------\n");

    // test-03: set seed to 1
    srand(1);
    printf("%d\n", rand());		// 41
    printf("%d\n", rand());		// 18476
    printf("%d\n", rand());		// 6334
    printf("--------------------\n");

    // test function time()
    long long timestamp = time(NULL);	// time_t: VC下为__int64(或long long)
    printf("The current time: %ld\n", timestamp);
    printf("--------------------\n");

    // test-04
    int i;
    for(i = 0; i < 100; i++)
    {
        srand((unsigned int)timestamp + i);
        printf("%d\n", rand());
    }								// ②结果相当有规律:+3或+4
    printf("--------------------\n");

    // test-05: A typical way to generate pseudo-random numbers in a determined range
    srand((unsigned int)time(NULL));
    printf("0-14: %d\n", rand() % 15);	// 0-14

    srand((unsigned int)time(NULL));
    printf("1970-1999: %d\n", rand() % 30 + 1970);	// 1970-1999
	printf("--------------------\n");

	// test-06: 一个容易犯的错误
	for(i = 0; i < 100; i++)
	{
		srand((unsigned int)time(NULL));			// note
		printf("%d\n", rand());
	}								// 输出全相同,因为在一个程序中time(NULL)每一次的返回值都相同
	printf("--------------------\n");

	// test-07: 貌似“不等概率”
	srand((unsigned int)time(NULL));
	for(i = 0; i < 100; i++)
	{
		printf("%d\n", rand());
	}								// 结果表现得貌似“不等概率”:100个数中5位数占大多数
    return 0;
}

/**
 * code-02: 等概率检验
 * 结果表明概率分布近似相等
 */
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define N (RAND_MAX+1)	// RAND_MAX is 32767
#define LOOP 10000000
int main()
{
	int count[N] = {0};
	int a;
	int i;
	srand((unsigned int)time(NULL));
	for(i = 0; i < LOOP; i++)
	{
		a = rand() % N;		// 0~RAND_MAX
		count[a]++;
	}
	for(i = (N - 1); i >= 0; i--)
	{
		printf("%d的个数:%d\n", i, count[i]);
	}
}