本来想系统地总结一下C语言中随机函数和计时函数的使用,因为在平时测试算法时经常用到。但简单调研之后发现水还是有点深度,所以就只把我用过证明可行的整理一下。在大多数情况下,我想这也一定足够了。
- rand()函数产生随机数
rand()函数产生的实际上是“伪随机数”(我没有听说迄今有哪个算法能产生真正的随机数),这个数是一个在区间[0, RAND_MAX]之间的整数,其中的上界是一个宏定义,其与rand()函数都定义在“stdlib.h”中。
stdlib中随机数的一个可能实现如下:
#define RAND_MAX 0x7fff unsigned long int next = 1; int rand(void) { next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % RAND_MAX; } /*srand函数:为rand函数设置种子数*/ void srand(unsigned int seed) { next = seed; }
因此,在调用rand函数前还要通过srand来“撒种”,一般情况下,可将其种子设为time(NULL),当然还要包含time.h头文件。
当然,如果要得到(0,1]上的随机数可以用“(rand()+1.0)/(RAND_MAX+1.0)”,得到(0,1)上的随机数可以将上式中换成“RAND_MAX+2.0”;得到小于某整数的随机数可以直接取模,用类似的方法可以得到任意区间的随机整数或浮点数值。
最后展示一个常见用法,是一个求PI的小程序:
#include <stdio.h> #include <stdlib.h> #include <time.h> #define PI 3.141592654 double HitorMiss(int n){ int k=0; double x, y; srand(time(NULL)); for (int i = 0; i < n; ++i) { x = (rand()+1.0) / (RAND_MAX+1.0); y = (rand()+1.0) / (RAND_MAX+1.0); if ((1.0-x*x)>=y*y) k++; } printf("RAND_MAX=%d\n", RAND_MAX); return 4.0*k/n; } int main(int argc, char *argv[]) { printf ("%f\n", HitorMiss(10000)); printf ("%f\n", HitorMiss(1000000)); printf ("%f\n", HitorMiss(100000000)); printf ("%f\n", HitorMiss(1000000000)); return 0; }
- clock()函数实现计时功能
函数clock()返回值为clock_t类型(实际上是一个长整型数),其实际意义是“进程启动到调用clock()函数经过了多少个CPU时钟计时单元”,借助CLOCKS_PER_SEC这个常量可以把clock_t转化为以秒为单位的数值。
一种典型的用法:
#include <time.h> ... int main(){ ... clock_t start, finish; start = clock(); for (i=1; i<times_to_test; i++){ search_A(4999); } finish = clock(); printf ("Time used: %.6f seconds.\n", (double)(finish-start)/CLOCKS_PER_SEC); ... }