C/C++中随机数的获取: 伪随机函数
2015-09-14 17:47
639 查看
1. C库中的伪随机函数rand的实现
《The GNU C Library》里说的,大概如下:
公式: Y=(a*X+c)mod m
其中,a,c,m都是常数
一种取值是:
a = 0x5DEECE66D = 25214903917
c = 0xb = 11
m = 2^48
用上面的公式可以这样写:
__int64 rand ()
{
static __int64 r = 0;
const __int64 a = 25214903917;
const __int64 c = 11;
const __int64 m = 1 << 48;
r = (r * a + c) % m;
return r;
}
2. ASNI 随机数生成的理解
ANSI中和随机数生成相关的函数是rand()和srand()。
rand()函数的原理:y=(a*x+b)mod n
ANSI通过记录最近生成的数来产生伪随机数。每次调用rand时,它取最近生成的一个数,对这个数执行一系列的操作,产生下一个数。
所以,在程序中如果多次调用rand的话,会生成不同的随机数。
但是,如果你多次运行同一个程序的话,产生的随机数序列是一样的,为什么会这样呢?主要是rand在设计的时候需要一个种子,这个种子作为整个随机数过程的起始值。开始运行程序时这个值是库里给定的,所以每次运行程序产生的随机数序列是一样的。
如果想产生不同的序列的话,就需要改变初始种子。使用srand函数用来设定种子。
可以利用每次运行程序时的时间来作为种子。这样就会产生不同的序列。
3. 随机数计算的相关
关于time_t time(0)
time_t 被定义为长整型,它将返回从1970年1月1日零时零分零秒到现在所经历过的时间,单位为秒。比如输出 cout<<time(0) ,将得到值约为1169174701,约等于37(年)* 365(天)* 24(小时)* 3600(秒)(月和日不计)。
关于ran_num=rand()%6
将rand()的返回值与6求模是必须的,这样才能确保目的随机数落在[0,6)之间,否则很可能会得到一个非常巨大的数值 (RAND_MAX一般为32767)。一个通用的公式是:要想取得[a,b)之间的随机整数,使用(rand()%(b-a))+ a,结果包含 a 而不含 b 。
4.随机函数 rand,srand,random,srandom 的区别与使用
使用方法 :
假如你想产生 1-10 之间的一个随机数, 你应该像下面这样编码
j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));
而不是下面这样的代码
j = 1 + (rand() % 10);
结论:如果你使用 srandom 种植种子, 则你应该使用 random 返回随机数, 如果你使用 srand 种植种子, 则你应该使用rand返回随机数。
不过srand和rand官方已经不推荐使用。原因是产生随机数的性能不是很好, 另外是随机数的随机性没有random好, 再者就是不是线程安全。
《The GNU C Library》里说的,大概如下:
公式: Y=(a*X+c)mod m
其中,a,c,m都是常数
一种取值是:
a = 0x5DEECE66D = 25214903917
c = 0xb = 11
m = 2^48
用上面的公式可以这样写:
__int64 rand ()
{
static __int64 r = 0;
const __int64 a = 25214903917;
const __int64 c = 11;
const __int64 m = 1 << 48;
r = (r * a + c) % m;
return r;
}
2. ASNI 随机数生成的理解
ANSI中和随机数生成相关的函数是rand()和srand()。
rand()函数的原理:y=(a*x+b)mod n
ANSI通过记录最近生成的数来产生伪随机数。每次调用rand时,它取最近生成的一个数,对这个数执行一系列的操作,产生下一个数。
所以,在程序中如果多次调用rand的话,会生成不同的随机数。
但是,如果你多次运行同一个程序的话,产生的随机数序列是一样的,为什么会这样呢?主要是rand在设计的时候需要一个种子,这个种子作为整个随机数过程的起始值。开始运行程序时这个值是库里给定的,所以每次运行程序产生的随机数序列是一样的。
如果想产生不同的序列的话,就需要改变初始种子。使用srand函数用来设定种子。
可以利用每次运行程序时的时间来作为种子。这样就会产生不同的序列。
3. 随机数计算的相关
关于time_t time(0)
time_t 被定义为长整型,它将返回从1970年1月1日零时零分零秒到现在所经历过的时间,单位为秒。比如输出 cout<<time(0) ,将得到值约为1169174701,约等于37(年)* 365(天)* 24(小时)* 3600(秒)(月和日不计)。
关于ran_num=rand()%6
将rand()的返回值与6求模是必须的,这样才能确保目的随机数落在[0,6)之间,否则很可能会得到一个非常巨大的数值 (RAND_MAX一般为32767)。一个通用的公式是:要想取得[a,b)之间的随机整数,使用(rand()%(b-a))+ a,结果包含 a 而不含 b 。
4.随机函数 rand,srand,random,srandom 的区别与使用
使用方法 :
假如你想产生 1-10 之间的一个随机数, 你应该像下面这样编码
j = 1 + (int) (10.0 * (rand() / (RAND_MAX + 1.0)));
而不是下面这样的代码
j = 1 + (rand() % 10);
结论:如果你使用 srandom 种植种子, 则你应该使用 random 返回随机数, 如果你使用 srand 种植种子, 则你应该使用rand返回随机数。
不过srand和rand官方已经不推荐使用。原因是产生随机数的性能不是很好, 另外是随机数的随机性没有random好, 再者就是不是线程安全。
相关文章推荐
- C/C++面试题-1
- C语言中重要函数的简要分析及实例
- 基于C++ 苹果apns消息推送实现(2)
- 【转】将Vim改造为强大的IDE—Vim集成Ctags/Taglist/Cscope/Winmanager/NERDTree/OmniCppComplete(有图有真相)
- C语言教程(C程序设计第三版)——清华大学
- C语言函数库
- C语言参考手册(第5版)
- C/C++程序员实用大全—C/C++最佳编程指南
- C语言深度剖析
- C语言核心技术
- 你必须知道的495个C语言问题
- C/C++代码精髓
- C++中指针的数据类型和运算相关知识小结
- 第2周项目3 体验复杂度(1)两种排序算法的运行时间
- C++Primer第五版 4.5节练习
- (转载)如何学好C语言
- C语言接口与实现[+]
- C++Primer第五版 第4章 表达式(练习解答)
- C++常量指针与常量数据
- 【第3周 项目1 - 顺序表的基本运算】