您的位置:首页 > 编程语言 > C语言/C++

CCRANDOM_0_1()其实不那么好用 爱上C++随机数的缘由

2014-07-11 11:49 246 查看
//rand()实际并不是一个真正的伪随机数发生器,random()会相对好点,但也不算理想。幸运的是iPhone上还有其他的选择。
//arc4random() 是个不错的选择,原因就是它是一个真正的伪随机算法,而且范围是rand()的两倍。
/*
在iPhone中,RAND_MAX是0x7fffffff (2147483647),而arc4random()返回的最大值则是 0x100000000 (4294967296),从而有更好的精度。此外,使用arc4random()还不需要生成随机种子,因为第一次调用的时候就会自动生成。
*/
//通过arc4random() 获取0到x-1之间的整数的代码如下:
//int value = arc4random() % x;
//获取1到x之间的整数的代码如下:
//int value arc4random() % x + 1;
//最后如果想生成一个浮点数,可以在项目中定义如下宏:
//#define ARC4RANDOM_MAX      0x100000000
//然后就可以使用arc4random() 来获取0到100之间浮点数了(精度是rand()的两倍),代码如下:
//double val = floorf(((double)arc4random() / ARC4RANDOM_MAX) * 100.0f);

//cocos2d-x里面是这样定义随机数的
//#define CCRANDOM_0_1() ((float)rand()/RAND_MAX)
//#define	RAND_MAX	0x7fffffff(标准库定义的额)

log("ar4:%u",arc4random());//u_int32_t arc4random(void);
/*
函数一:int rand(void);
返回一个[0,RAND_MAX]间的随机整数。
函数二:void srand(unsigned seed);
参数seed是rand()的种子,用来初始化rand()的起始值。
*/
//可以用以下两种方式产生随机种子
srand((unsigned)time(0));
srand((unsigned)time(NULL));
rand();
random();
//time_t time(0):time_t被定义为长整型,它返回从1970年1月1日零时零分零秒到目前为止所经过的时间,单位为秒。
log("Long : %ld", time(0));


最近发现C++11提供了新的随机数机制,感觉非常给力。

需要引入头文件

#include <random>
/*
新设施利用两部分来生成随机数:

random number engines . 负责生成原始随机数
random number distributions . 迫使生成的随机数在统计上满足指定的概率分布

STL预先指定了一系列的生成引擎,并且提供一个 default_random_engine 。
default_random_engine 会使用某个预定义的引擎,且不同编译器,不同平台的实现可能不同。
*/
std::default_random_engine e;
printf("the e() is %u", e());//产生随机数

/*
默认情况下,引擎产生的随机数范围在
default_randm_engine::min 和 default_random_engine::max 之间。
*/
printf("min:%u\n",std::default_random_engine::min());//1
printf("max:%u\n",std::default_random_engine::max());//2147483646
/*
有了引擎,我们可以指定随机数要符合的分布性质,例如说,在([5,20])上的均匀分布
*/
std::uniform_int_distribution<> u(5,20);
for (size_t i = 0; i < 10; i++) {
std::cout << u(e) << std::endl;
}

/*
上面那两个函数生成的随机数,在我测试的时候每次都是一样的。不知道原因,但是感觉巨坑。可能从头到尾都只给了一次种子吧。强烈推荐最后这种生成方法。
C++11提供了一个非常友好的类: random_device 。
这个类的作用是,可以产生 non-deterministic random numbers .

这个类有可能产生真正的随机数,不过真是效果和具体实现有关。
某些平台可能才用伪随机数作为底层实现也说不定呢…
显然的,我们可以利用 random_device 去初始化我们的随机数种子

*/
std::random_device rd;
std::default_random_engine e_real(rd());
std::uniform_int_distribution<> u_real(5,20);
for (size_t i = 0; i < 10; i++) {
std::cout << u_real(e_real) << std::endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: