当前位置:  开发笔记 > 编程语言 > 正文

C的rand()使用了哪些常用算法?

如何解决《C的rand()使用了哪些常用算法?》经验,为你挑选了2个好方法。

据我所知,C规范没有给出任何关于具体实现的规范rand().在不同的主要平台上通常使用哪些不同的算法?他们有什么不同?



1> Aaron Digull..:

请参阅此文章:http://en.wikipedia.org/wiki/List_of_random_number_generators

这是glibc的源代码rand():

/* Reentrant random function from POSIX.1c.
   Copyright (C) 1996, 1999, 2009 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Ulrich Drepper , 1996.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include 


/* This algorithm is mentioned in the ISO C standard, here extended
   for 32 bits.  */
int
rand_r (unsigned int *seed)
{
  unsigned int next = *seed;
  int result;

  next *= 1103515245;
  next += 12345;
  result = (unsigned int) (next / 65536) % 2048;

  next *= 1103515245;
  next += 12345;
  result <<= 10;
  result ^= (unsigned int) (next / 65536) % 1024;

  next *= 1103515245;
  next += 12345;
  result <<= 10;
  result ^= (unsigned int) (next / 65536) % 1024;

  *seed = next;

  return result;
}

资料来源:https://sourceware.org/git/?p = glibc.git; a = blob_plain; f = stdlib/num_r.c; hb = HEAD

正如您所看到的,它只是乘以加法和移位.仔细选择这些值以确保不会重复RAND_MAX迭代的输出.

请注意,这是一个旧的实现,已被更复杂的算法所取代:https://sourceware.org/git/?p = glibc.git; a = blob_plain; f = stdlib/random_r.c; hb = HEAD

如果链接断开,谷歌为"glibc rand_r"



2> eloj..:

我曾经为CRNG撰写了一篇关于离散数学课程的报告.为此,我在msvcrt.dll中反汇编了rand():

msvcrt.dll:77C271D8 mov     ecx, [eax+14h]
msvcrt.dll:77C271DB imul    ecx, 343FDh
msvcrt.dll:77C271E1 add     ecx, 269EC3h
msvcrt.dll:77C271E7 mov     [eax+14h], ecx
msvcrt.dll:77C271EA mov     eax, ecx
msvcrt.dll:77C271EC shr     eax, 10h
msvcrt.dll:77C271EF and     eax, 7FFFh

所以这是一个类似(未经测试)的LCG ......

int ms_rand(int& seed)
{
  seed = seed*0x343fd+0x269EC3;  // a=214013, b=2531011
  return (seed >> 0x10) & 0x7FFF;
}

推荐阅读
大大炮
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有