伪随机数问题笔记 C++

伪随机数问题笔记

  计算机中随机数由“随机种子”产生。“随机种子”是一个无符号整形数。以下程序阐述了随机数产生的过程:

#include
static unsigned int RAND_SEED;
unsigned int random(void)
{
    RAND_SEED=(RAND_SEED*123+59)%65536;
    return(RAND_SEED);
}
void random_start(void)
{
    int temp[2];
    movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);
    RAND_SEED=temp[0];
}
main()
{
    unsigned int i,n;
    random_start();
    for(i=0;i<10;i++)
        printf("%u/t",random());

    printf("/n");
}


  主程序调用random_start():
    movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);
移动内存数据,其中FP_SEG(far pointer to segment)是取temp数组段地址的函数,FP_OFF(far pointer to offset)是取temp数组相对地址的函数,movedata函数把位于0040:006CH存储单元中的双字放到数组temp的声明的两个存储单元中。这样可以通过temp数组把0040:006CH处的一个16位的数送给RAND_SEED。

random根据随机种子RAND_SEED的值计算出随机数:
    RAND_SEED=(RAND_SEED*123+59)%65536;

  关键点:随机种子为什么要在内存的0040:006CH处取?

  计算机主机板上有一个定时/记数器用来计算当前系统时间,每过一个时钟信号周期记数器加 1,这个记数器的值存放在内存的0040: 006CH处。

  内存定义:
    TIMER_LOW DW ?  ;  地址为 0040:006CH
    TIMER_HIGH DW ? ; 地址为 0040:006EH
    TIMER_OFT DB ? ;   地址为 0040:0070H

  时钟中断服务程序中,每当TIMER_LOW转满时,此时,记数器也会转满,记数器的值归零,即TIMER_LOW处的16位二进制归零,而TIMER_HIGH 加 1 。
movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);
把TIMER_LOW和TIMER_HIGH两个16位二进制数放进temp数组,再送往RAND_SEED ,获得“随机种子”。

  结论:随机种子来自系统时钟,来自计算机主板上的定时/计数器在内存中的记数值。

  推论:1. 随机种子一定,产生的随机数不变。

#include
using namespace std;
int main()
{
    unsigned int seed=930;
    srand(seed);
    cout<<rand()<<endl;
    return 0;
}

  2.设随机种子来自系统时钟,每次运行显示的结果会不同。

#include
using namespace std;
int main()
{
    srand((unsigned)time(NULL));
    cout<<rand()<<endl;
    return 0;
}

  这样的随机数要经过改造才能用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值