据我所知,C规范没有给出任何关于具体实现的规范rand()
.在不同的主要平台上通常使用哪些不同的算法?他们有什么不同?
请参阅此文章: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"
我曾经为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; }