rand函数的实现原理

rand函数的实现原理

rand函数产生的是伪随机数,也就是说它不是一个真实的随机数。

那么伪随机数是怎么实现的呢?原理大概如下:

如果约定:a1=f(seed),an+1=f(an)那你可以行到一个序列:a1,a2,a3...an,那么要制作一个伪随机函数rand,只需要让它每调用一次就返回序列的下一个元素就行。

就相当于第1次调用rand返回a1,第2次返回a2,…,第n次返回an,这样每次调rand都能拿到一个不同的数,只要整个序列的规律不明显,整个函数看起来就是随机的。

现在计算机上的rand函数都是用这样的原理实现的,这里的seed被称为“随机数种子”。

但这里有一个问题,如果seed不变,那我们每次调用rand函数获取的序列都是相同的。这就会造成有的程序跑一遍退出后,再重新跑一遍,两次的输出结果是相同的。所以我们还需要一个接口去设置seed值,这个接口就是srand函数。

linux下的rand是用类似下面的代码实现的:

static unsigned long next = 1;

/* RAND_MAX assumed to be 32767 */
int myrand(void) {
    next = next * 1103515245 + 12345;
    return((unsigned)(next/65536) % 32768);
}

void mysrand(unsigned seed) {
    next = seed;
}

myrandmysrand分别对应randsrand,但实际的rand实现会复杂一些。

使用rand函数的一个问题

有些人使用rand函数时,因为初始化时没有调用srand会造成程序每次运行输出结果都相同:http://ask.csdn.net/questions/174871

如果你没有调用srand设置随机数种子,seed的默认值会是0,而seed为0时所决定的序列是固定的,而第一次调用rand()就是返回这个固定序列里的第1个元素,那它的值也是固定的,自然你的程序每次输出都一样了。

所以正确的写法应该是程序初始化时用srand设置不同的随机数种子(只需要设置一次),例如srand(time(NULL)),但要注意,time(NULL)的值是隔1秒才改变一次的,必要情况下可以考虑使用精度更高的时间函数,如gettimeofday

下面这段程序,只要你不是在同一秒内执行两次,每次输出结果都是不一样的:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    srand(time(NULL));     // 设置随机数种子
    for (int i = 0; i < 10; i++)
    {
        printf("%u\n", rand());
    }
    getchar();
    return 0;
}
时间: 2024-10-10 16:40:01

rand函数的实现原理的相关文章

PHP函数的实现原理及性能分析

前言 在任何语言中,函数都是最基本的组成单元.对于php的函数,它具有哪些特点?函数调用是怎么实现的?php函数的性能如何,有什么使用建议?本文将从原理出发进行分析结合实际的性能测试尝试对这些问题进行回答,在了解实现的同时更好的编写php程序.同时也会对一些常见的php函数进行介绍. php函数的分类 在php中,横向划分的话,函数分为两大类: user function(用户函数) 和internal function(内置函数).前者就是用户在程序中自定义的一些函数和方法,后者则是php本身

(转)PHP 函数的实现原理及性能分析

前言 任何语言中,函数都是最基本的组成单元.对于php的函数,它具有哪些特点?函数调用是怎么实现的?php函数的性能如何,有什么使用建议?本文 将从原理出发进行分析结合实际的性能测试尝试对这些问题进行回答,在了解实现的同时更好的编写php程序.同时也会对一些常见的php函数进行介绍. php函数的分类 在php中,横向划分的话,函数分为两大类: user function(内置函数) 和internal function(内置函数).前者就是用户在程序中自定义的一些函数和方法,后者则是php本身

php MySQL使用rand函数随机取记录(转)

php MySQL使用rand函数随机取记录 如何在mysql中使用随机数, 如何写一个语句能一下更新几百条MYSQL数据! 需要测试MYSQL数据库,里面有一个上万条数据的数据库,如何写一个PHP文件一下每次更新几百条信息,我都是写一个循环一次更新一条信息,这样我知道用WHILE写就可以了,要是一次更新好比100条数据改如何写呢! 正确答案是:UPDATE cdb_posts SET views = rand(); 顺便给你找了点关于mysql rand函数的实例,如下: 那就在insert

matlab rand函数详解

均匀分布的随机数或矩阵 语法 Y = rand(n) Y = rand(m,n) Y = rand([m n]) Y = rand(m,n,p,...) Y = rand([m n p...]) Y = rand(size(A)) rand s = rand('state') 描述 rand函数产生由在(0, 1)之间均匀分布的随机数组成的数组. Y = rand(n) 返回一个n x n的随机矩阵.如果n不是数量,则返回错误信息. Y = rand(m,n) 或 Y = rand([m n])

几个常见字符串处理函数的实现原理

字符串是一种常见的数据结构,对字符串的处理又可以十分灵活,所以在实际开发,尤其是非数值处理中,字符串的应用非常广泛.虽然很多字符串操作都封装在了函数库里,应用程序可以直接通过调用库函数来实现字符串处理,然而对于开发者而言,若能了解其底层实现原理,对于应用编程而言还是大有裨益的. 这篇文章主要介绍几种常用的字符串处理函数的实现原理. 一.strlen函数 strlen函数:计算字符串的实际长度,不包括'\0'. 算法:从第一个字符开始扫描,直到遇见第一个'\0',停止扫描,返回字符串长度. 代码如

关于rand()函数 转载于其他人

C++中的rand()函数 分类: 编程语言/ C#/ 文章 C++中产生随机数种子对于初学者一直都很困惑.大家知道,在C中有专门的srand(N)函数可以轻松实现这一功能,然而在C++中则要复杂一些.下面是笔者学习的一点心得,希望对大家能有所帮助.(这里我们依然要借助C标准库中的rand()函数) 函数说明: int rand();                                          :返回从[0,MAX)之间的随机整数,这里的MAX与你所定义的数据类型而定:需#

C語言 rand函数 进阶探讨与实现

C语言中随机函数应用 可能大家都知道C语言中的随机函数random,可是random函数并不是ANSI C标准,所以说,random函数不能在gcc,vc等编译器下编译通过.那么怎么实现C语言中的随机函数呢? 除了random函数,还有一个rand函数,也是一个随机函数,可以产生从0到rand_max的随机数. #include <stdio.h> #include <stdlib.h> int main() { int x; x = rand(); printf("%d

关于rand函数

C语言要获得随机数,就要用到rand()函数.关于rand函数要注意以下几点: 1.要包含stdlib.h,rand函数声明在这个函数里. 2.rand()函数返回一个0~RAND_MAX之间的随机数,经测试在VC,GCC中,[0,RAND_MAX],这个随机数是可以是0或RAND_MAX的. 3.rand()产生的是伪随机数,如果不初始化,每次输出都是一样的序列. 4.srand(seed)是初始化函数,seed一般用机器时间. RAND_MAX是跟实现有关的,在VC6里是32767,在GCC

PHP的ip2long和long2ip函数的实现原理

最近要做个十进制数字的可逆转换做邀请码,一直没搞清楚怎么弄的,实在太复杂了,今天弄IP时想到这个可以进行转换,于是研究了下原理: 主要是自己整理了下: $ip = '12.34.56.78'; $ips = explode('.', $ip); $result = 0; $result += $ips[0]<<24; $result += $ips[1]<<16; $result += $ips[2]<<8; $result += $ips[3]; echo binde