很多时候我们期望使用随机数来测试我们的结果,在C99中有给出2个随机函数
int rand(void);
void srand(unsigned int seed);
CLIB中,在 \StdLib\Include\stdlib.h 有如下定义
/* ################ Pseudo-random sequence generation functions ######### */ /** The rand function computes a sequence of pseudo-random integers in the range 0 to RAND_MAX. @return The rand function returns a pseudo-random integer. **/ int rand(void); /** The srand function uses the argument as a seed for a new sequence of pseudo-random numbers to be returned by subsequent calls to rand. If srand is then called with the same seed value, the sequence of pseudo-random numbers shall be repeated. If rand is called before any calls to srand have been made, the same sequence shall be generated as when srand is first called with a seed value of 1. **/ void srand(unsigned seed);
前者rand 是“伪随机”数,因为生成随机数的种子是固定的,所以每次生成的序列都是相同的。比如,我们用下面的程序段测试:
printf("1st time generated by rand()\n"); for (i=0;i<5;i++) { printf("%d ",rand()); } printf("\n"); printf("2nd time generated by rand()\n"); for (i=0;i<5;i++) { printf("%d ",rand()); } printf("\n");
得到的结果如下,可以看出来:生成的数值之间是随机的,但是每次运行生成的序列是一样的。这也就是“伪随机”的由来。
此外,在程序的开始处,运行 srand 指定一个种子,就可以让 rand生成“随机数”。运行 srand的结果如下:
进一步分析随机函数,可以在 \StdLib\LibC\StdLib\Rand.c 看到
static UINT32 next = 1; /** Compute a pseudo-random number. * * Compute x = (7^5 * x) mod (2^31 - 1) * without overflowing 31 bits: * (2^31 - 1) = 127773 * (7^5) + 2836 * From "Random number generators: good ones are hard to find", * Park and Miller, Communications of the ACM, vol. 31, no. 10, * October 1988, p. 1195. **/ int rand() { INT32 hi, lo, x; /* Can't be initialized with 0, so use another value. */ if (next == 0) next = 123459876; hi = next / 127773; lo = next % 127773; x = 16807 * lo - 2836 * hi; if (x < 0) x += 0x7fffffff; return ((next = x) % ((UINT32)RAND_MAX + 1)); } void srand(unsigned int seed) { next = (UINT32)seed; }
就是说当我们使用 rand 函数的时候,种子 static UINT32 next = 1; 默认为 1.而当我们首先给定一个种子的时候,next会被替换为我们指定的值。从而达到随机的目的。(话说感觉这样做出来的随机似乎也不是很可靠。如果我们有足够多的序列,完全也能推测出随机种子,也能预测出下面将要出现的数值)
一般随机种子都是直接取当前的时间,于是写一个是程序验证:
#include <Uefi.h> #include <Library/UefiLib.h> #include <Library/ShellCEntryLib.h> #include <stdio.h> #include <stdlib.h> #include <wchar.h> #include <time.h> #include <Protocol/EfiShell.h> #include <Library/ShellLib.h> extern EFI_BOOT_SERVICES *gBS; extern EFI_SYSTEM_TABLE *gST; extern EFI_RUNTIME_SERVICES *gRT; int EFIAPI main ( IN int Argc, IN char **Argv ) { INTN i; time_t t; printf("1st time generated by rand()\n"); for (i=0;i<5;i++) { printf("%d ",rand()); } printf("\n"); printf("2nd time generated by rand()\n"); for (i=0;i<5;i++) { printf("%d ",rand()); } printf("\n"); printf("Generated by srand()\n"); time(&t); srand(t); for (i=0;i<5;i++) { printf("%d ",rand()); } printf("\n"); return EFI_SUCCESS; }
这个程序工作正常,不过有一个“奇怪”的现象:当你连续运行这个程序的时候,2nd time generated by rand() 生成的序列有时候会相同,您说这是为什么呢?
完整程序代码下载
rand
参考:
1.http://blog.csdn.net/zhenyongyuan123/article/details/5810253 C99标准库函数