本文由青松原创并依GPL-V2及其后续版本发放,转载请注明出处且应包含本行声明。

C++中常用rand()函数生成随机数,但严格意义上来讲生成的只是伪随机数(pseudo-random integral number)。生成随机数时需要我们指定一个种子,如果在程序内循环,那么下一次生成随机数时调用上一次的结果作为种子。但如果分两次执行程序,那么由于种子相同,生成的“随机数”也是相同的。

在工程应用时,我们一般将系统当前时间(Unix时间)作为种子,这样生成的随机数更接近于实际意义上的随机数。给一下例程如下:

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std; int main()
{
double random(double,double);
srand(unsigned(time(0)));
for(int icnt = 0; icnt != 10; ++icnt)
cout << "No." << icnt+1 << ": " << int(random(0,10))<< endl;
return 0;
} double random(double start, double end)
{
return start+(end-start)*rand()/(RAND_MAX + 1.0);
}
/* 运行结果
* No.1: 3
* No.2: 9
* No.3: 0
* No.4: 9
* No.5: 5
* No.6: 6
* No.7: 9
* No.8: 2
* No.9: 9
* No.10: 6
*/
利用这种方法能不能得到完全意义上的随机数呢?似乎9有点多哦?却没有1,4,7?!我们来做一个概率实验,生成1000万个随机数,看0-9这10个数出现的频率是不是大致相同的。程序如下:
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <iomanip>
using namespace std; int main()
{
double random(double,double);
int a[10] = ;
const int Gen_max = 10000000;
srand(unsigned(time(0))); for(int icnt = 0; icnt != Gen_max; ++icnt)
switch(int(random(0,10)))
{
case 0: a[0]++; break;
case 1: a[1]++; break;
case 2: a[2]++; break;
case 3: a[3]++; break;
case 4: a[4]++; break;
case 5: a[5]++; break;
case 6: a[6]++; break;
case 7: a[7]++; break;
case 8: a[8]++; break;
case 9: a[9]++; break;
default: cerr << "Error!" << endl; exit(-1);
} for(int icnt = 0; icnt != 10; ++icnt)
cout << icnt << ": " << setw(6) << setiosflags(ios::fixed) << setprecision(2) << double(a[icnt])/Gen_max*100 << "%" << endl; return 0;
} double random(double start, double end)
{
return start+(end-start)*rand()/(RAND_MAX + 1.0);
}
/* 运行结果
* 0: 10.01%
* 1: 9.99%
* 2: 9.99%
* 3: 9.99%
* 4: 9.98%
* 5: 10.01%
* 6: 10.02%
* 7: 10.01%
* 8: 10.01%
* 9: 9.99%
*/
可知用这种方法得到的随机数是满足统计规律的。 另:在Linux下利用GCC编译程序,即使我执行了1000000次运算,是否将random函数定义了inline函数似乎对程序没有任何影响,有理由相信,GCC已经为我们做了优化。但是冥冥之中我又记得要做inline优化得加O3才行... 不行,于是我们把循环次数改为10亿次,用time命令查看执行时间:
chinsung@gentoo ~/workspace/test/Debug $ time ./test
0: 10.00%
1: 10.00%
2: 10.00%
3: 10.00%
4: 10.00%
5: 10.00%
6: 10.00%
7: 10.00%
8: 10.00%
9: 10.00% real 2m7.768s
user 2m4.405s
sys 0m0.038s
chinsung@gentoo ~/workspace/test/Debug $ time ./test
0: 10.00%
1: 10.00%
2: 10.00%
3: 10.00%
4: 10.00%
5: 10.00%
6: 10.00%
7: 10.00%
8: 10.00%
9: 10.00% real 2m7.269s
user 2m4.077s
sys 0m0.025s 前一次为进行inline优化的情形,后一次为没有作inline优化的情形,两次结果相差不大,甚至各项指标后者还要好一些,不知是何缘由...

C++利用系统时间产生的随机数的更多相关文章

  1. SQLserver利用系统时间生成“2015-11-30 00:00:00.000”类型的时间

    select getdate() ---当前时间:2015-12-18 10:20:24.097 -------------------建立测试表 Create Table #Test ( ID IN ...

  2. C++11新特性,利用std::chrono精简传统获取系统时间的方法

    一.传统的获取系统时间的方法 传统的C++获取时间的方法须要分平台来定义. 相信百度代码也不少. 我自己写了下,例如以下. const std::string getCurrentSystemTime ...

  3. c++ 怎样获取系统时间

    c++ 怎样获取系统时间 2008-04-28 15:34 //方案— 长处:仅使用C标准库:缺点:仅仅能精确到秒级 #include <time.h> #include <stdi ...

  4. JAVA中获取当前系统时间及格式转换

    JAVA中获取当前系统时间   一. 获取当前系统时间和日期并格式化输出: import java.util.Date;import java.text.SimpleDateFormat; publi ...

  5. Java 获取当前系统时间方法比较

    转载: http://blog.csdn.net/zzjjiandan/article/details/8372617 一. 获取当前系统时间和日期并格式化输出: import java.util.D ...

  6. c++获取系统时间(引用别人的博文)

    //方案— 优点:仅使用C标准库:缺点:只能精确到秒级#include <time.h> #include <stdio.h> int main( void ) {     t ...

  7. java获取获得Timestamp类型的当前系统时间。以及java.util.date 、java.sql.Date之间的转换

    java获取取得Timestamp类型的当前系统时间java获取取得Timestamp类型的当前系统时间 格式:2010-11-04 16:19:42 方法1: Timestamp d = new T ...

  8. JAVA中获取当前系统时间

    一. 获取当前系统时间和日期并格式化输出: import java.util.Date;import java.text.SimpleDateFormat; public class NowStrin ...

  9. java获取获得Timestamp类型的当前系统时间

    java获取取得Timestamp类型的当前系统时间java获取取得Timestamp类型的当前系统时间 格式:2010-11-04 16:19:42 方法1: Timestamp d = new T ...

随机推荐

  1. Jquery 中的 event、event.target 和原生JS的 event、event.target 对比

    先看下原生的 event,如图: 再看下 Jquery 中的 event,如图: 明显不一样,也符合常理,比较结果: 那么如何把 Jquery 中的 event 转成原生的呢?  event.orig ...

  2. Python目录整合

    一.python基础篇 二.网络编程篇&&并发编程篇 三.数据库篇 -mysql -redis -mongodb 四.前端篇 -html -css -js jquery&&am ...

  3. 【转】Spring Boot 日志配置(超详细)

    更新日志: 20170810 更新通过 application.yml传递参数到 logback 中. [toc] 简书不支持目录,截图一张. image.png 默认日志 Logback: 默认情况 ...

  4. java基础04 Scanner的使用

    import java.util.Scanner; /** * 所有在java.lang包下面的所有类 不需要显示的引入包! * java.util.Scanner : 想获取用户的输入 必须引入相关 ...

  5. 汉诺塔IV---hdu2077

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2077 #include <stdio.h> #include <stdlib.h&g ...

  6. android推送,极光推送

    android中简单易用的消息推送方式之中的一个 -------> 极光推送 首先来介绍一下极光推送. 极光推送:英文简称 JPush,是一个面向普通开发人员免费.开放的第三方消息推送服务,我们 ...

  7. Java设计模式-简单工厂模式(Static Factory Method)

    简单工厂模式(Static Factory Method) 简单工厂模式是类的创建模式,又叫静态工厂方法(Static Factory Method)模式.简单工厂模式是由一个工厂对象决定创建出哪一种 ...

  8. vs中nodejs代码 resharper 提示 ECMAScript2015 Feature. your Current language level is ECMAScript5的解决办法

    问题如图 错误信息:ECMAScript 2015 Feature. your Current language level is: ECMAScript5 解决方法, 打开 Resharper -& ...

  9. 安卓android的联系人的contacts, raw contacts, and data的区别

    https://stackoverflow.com/questions/5151885/android-new-data-record-is-added-to-the-wrong-contact/51 ...

  10. w命令

    命 令:w 功能说明:显示目前登入系统的用户信息. 语 法:w [-fhlsuV][用户名称] 补充说明:执行这项指令可得知目前登入系统的用户有那些人,以及他们正在执行的程序.单独执行w 指令会显示所 ...