很多时候我们期望使用随机数来测试我们的结果,在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标准库函数
















