本篇文章介绍ISO C
标准的伪随机数生成函数,包含rand
、srand
和rand_r
函数。
头文件
#include <stdlib.h>
rand
int rand(void)
返回一个在[0, RAND_MAX]
区间的随机整数,rand函数为非线程安全函数,某些 rand()
的旧版本实现在随机性、分布和产生的数列周期中有严重缺陷,推荐使用drand48
。
RAND_MAX:rand函数能返回的最大值,在GNU C
库中是32位的有符号整数最大值2147483647
,在其他库中可能是32767
。
srand
void srand(unsigned int seed)
设置rand函数的种子, 如果没有设置seed种子,rand函数使用默认种子srand(1)
,使用同一seed种子,rand函数会产生相同的随机值数列,srand函数不保证线程安全;
rand_r
int rand_r(unsigned int *seedp)
rand函数的线程安全版本,是可重入函数,RNG状态由seedp参数决定,也就意味着只有unsigned int
大小的状态,所以rand_r是一个weak RNG,可以考虑使用drand48_r
代替。
示例实现
#define RADN_MAX 0X7FFF /* RADN_MAX 32767 */
sratic unsigned long next = 1;
int rand(void)
{
next = next * 1103515245 + 12345;
return((unsigned)(next/65536) % 32768);
}
void srand(unsigned int seed)
{
next = seed;
}
int rand_r (unsigned int *seed)
{
unsigned int next = *seed;
int result;
next *= 1103515245;
next += 12345;
result = (unsigned int) (next / 65536) % 2048;
next *= 1103515245;
next += 12345;
result <<= 10;
result ^= (unsigned int) (next / 65536) % 1024;
next *= 1103515245;
next += 12345;
result <<= 10;
result ^= (unsigned int) (next / 65536) % 1024;
*seed = next;
return result;
}
生成指定范围[m,n]的随机数
int random_number = rand()%(n-m+1) + m;
示例代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
srand(time(NULL)); // 以当前时间为随机生成器的种子
int random_variable = rand();
printf("Random value on [0,%d]: %d\n", RAND_MAX, random_variable);
static int seed = time(NULL);
int random_number = rand_r(&seed);
printf("Random value on [0,%d]: %d\n", RAND_MAX, random_number);
return 0;
}