⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 randomnumbersin c_bygeorgemarsaglia_etc.htm

📁 QPSK环境下的仿真性能分析
💻 HTM
📖 第 1 页 / 共 5 页
字号:
use in C. (See the thread "Random numbers for C: Somesuggestions" in previous postings.) The improved codeis listed below.A question of copyright has also been raised.  UnlikeDIEHARD, there is no copyright on the code below. Youare free to use it in any way you want, but you maywish to acknowledge the source, as a courtesy.To avoid being cited by the style police, some havesuggested using typedef rather than #define in orderto replace unsigned long by UL.Others have pointed out that one cannot be certain ofthe way that a compiler will evaluate terms in a sum,so using ++c in a term is dangerous.  They haveoffered a version using the comma operator, whichensures that the table index is incremented properly.See LFIB4 and SWB below.In my earlier work, done in Fortran, I had implementedtwo 16-bit multiply-with-carry generators, say z and w,as 32-bit integers, with the carry in the top 16 bits,the output in the bottom 16.  They were combined by(z&LT;&LT;16)+w.  (In Fortran, ishft(z,16)+w.) Such acombination seemed to pass all tests. In the above-mentioned post,  I used (z&LT;&LT;16)+(w&65525), and thatdoes not pass all tests.  So (z&LT;&LT;16)+w seemspreferable; it is used below, providing a MWC thatseems to pass all tests. The generators MWC, KISS, LFIB4 and SWB seem to pass all tests.By themselves, CONG and SHR3 do not, but usingCONG+SHR3 provides one of the fastest combinations that satisfythe DIEHARD battery of tests.Of course, one cannot have absolute confidence in anygenerator. The choices LFIB4 and SWB have immenseperiods, are very fast, and pass all tests in DIEHARD,but I am hesitant to rely on them alone---primarilybecause they come from such simple mod 2^32 arithmetic:four adds in LFIB4 or one subtract-with-borrow in SWB.The code below provides  a variety of in-line generators thatseem promising by themselves, and even more so in combination.With them,  one may feel fairly confident  that combinationswill produce results  consistent with the underlying probability theoryin your applications.All combinations seem to support the supplemented quotefrom my 1984 Keynote Address:       A random number generator is like sex;       When it's good, it's wonderful,       And when it's bad, it's still pretty good.       And when it's bad, try a twosome or threesome.The C code follows; you may want to snip and save fromhere--------------------------------------------------:#define znew  (z=36969*(z&65535)+(z>>16))#define wnew  (w=18000*(w&65535)+(w>>16))#define MWC   ( (znew&LT;&LT;16)+wnew )#define SHR3  (jsr=(jsr=(jsr=jsr^(jsr&LT;&LT;17))^(jsr>>13))^(jsr&LT;&LT;5))#define CONG  (jcong=69069*jcong+1234567)#define KISS  ((MWC^CONG)+SHR3)#define LFIB4 (t[c]=t[c]+t[c+58]+t[c+119]+t[c+178],t[++c])#define SWB   (t[c+237]=(x=t[c+15])-(y=t[c]+(x&LT;y)),t[++c])#define UNI   (KISS*2.328306e-10)#define VNI   ((long) KISS)*4.656613e-10typedef unsigned long UL;/*  Global static variables: */ static UL z=362436069, w=521288629, jsr=123456789, jcong=380116160; static UL t[256]; static UL x=0,y=0; static unsigned char c=0;/* Random seeds must be used to reset z,w,jsr,jcong andthe table t[256].  Here is an example procedure, using KISS: */ void settable(UL i1,UL i2,UL i3,UL i4) { int i; z=i1;w=i2,jsr=i3; jcong=i4; for(i=0;i&LT;256;i++)  t[i]=KISS;        }/* Any one of KISS, MWC, LFIB4, SWB, SHR3, or CONG  can be used in   an expression to provide a random 32-bit integer, while UNI   provides a real in (0,1) and VNI a real in (-1,1).   */<HR><A NAME = "790f49x60.fsf@poole.statgen.ncsu.edu"></A>Subject: Re: Random numbers for C: Improvements.Date: 15 Jan 1999 14:02:47 -0500From: zaykin@statgen.ncsu.edu (Dmitri Zaykin)Message-ID: &LT;790f49x60.fsf@poole.statgen.ncsu.edu>References: <A HREF = "#369F6FCA.74C7C041@stat.fsu.edu">&LT;369F6FCA.74C7C041@stat.fsu.edu></A>Newsgroups: sci.stat.math,sci.math,sci.math.num-analysisLines: 11George Marsaglia &LT;geo@stat.fsu.edu> writes:> #define LFIB4 (t[c]=t[c]+t[c+58]+t[c+119]+t[c+178],t[++c])> #define SWB   (t[c+237]=(x=t[c+15])-(y=t[c]+(x&LT;y)),t[++c])Shouldn't these be#define LFIB4 (t[c]=t[c]+t[c+58]+t[c+119]+t[c+179], ++c)#define SWB   (t[c+237]=(x=t[c+15])-(y=t[c+1]+(x&LT;y)), ++c)Dmitri<HR><A NAME = "99Jan15.151547edt.785@neuron.ai.toronto.edu"></A>Subject: Re: Random numbers for C: Improvements.Date: 15 Jan 99 20:16:13 GMTFrom: radford@cs.toronto.edu (Radford Neal)Message-ID: &LT;99Jan15.151547edt.785@neuron.ai.toronto.edu>References: <A HREF = "#790f49x60.fsf@poole.statgen.ncsu.edu">&LT;790f49x60.fsf@poole.statgen.ncsu.edu></A>Newsgroups: sci.math,sci.math.num-analysis,sci.stat.mathLines: 28>George Marsaglia &LT;geo@stat.fsu.edu> writes:>>> #define LFIB4 (t[c]=t[c]+t[c+58]+t[c+119]+t[c+178],t[++c])>> #define SWB   (t[c+237]=(x=t[c+15])-(y=t[c]+(x&LT;y)),t[++c])>In article &LT;790f49x60.fsf@poole.statgen.ncsu.edu>,Dmitri Zaykin &LT;zaykin@statgen.ncsu.edu> wrote:>Shouldn't these be>>#define LFIB4 (t[c]=t[c]+t[c+58]+t[c+119]+t[c+179], ++c)>#define SWB   (t[c+237]=(x=t[c+15])-(y=t[c+1]+(x&LT;y)), ++c)>This doesn't work either.  I believe that it is undefined whether thecomparison x&LT;y uses the new or the old value of x.  The SHR3 macroin the original source also suffers from this flaw.I think one needs to face up to an unpleasant truth:  The #define facility of C was poorly designed, and is incapable in general ofsupporting the definition of "in-line" procedures.  It is far betterto simply write ordinary C procedures, and accept the fairly smallprocedure call overhead.   Radford Neal<HR><A NAME = "QfQn2.10695$bf6.2024@news1.giganews.com"></A>Subject: Re: Random numbers for C: Improvements.Date: Fri, 15 Jan 1999 17:34:36 -0600From: "Jeff Stout" &LT;jstout@ncon.com>Message-ID: &LT;QfQn2.10695$bf6.2024@news1.giganews.com>References: <A HREF = "#99Jan15.151547edt.785@neuron.ai.toronto.edu">&LT;99Jan15.151547edt.785@neuron.ai.toronto.edu></A>Newsgroups: sci.math,sci.math.num-analysis,sci.stat.mathLines: 27Radford Neal wrote in message&LT;99Jan15.151547edt.785@neuron.ai.toronto.edu>...>>>I think one needs to face up to an unpleasant truth:  The #define>facility of C was poorly designed, and is incapable in general of>supporting the definition of "in-line" procedures.  It is far better>to simply write ordinary C procedures, and accept the fairly small>procedure call overhead.>>   Radford Neal>>This is not a poor design of the macro facility of C, but a built inlimitation of the C language itself.  The preprocessor is just doinga stupid text substituation, its the C compiler that is ambigous aboutthe interpretationThe C macro language can support "in-line" procedures and a lotof other junk only true software wienies would ever use.Jeff Stout<HR><A NAME = "99Jan15.233424edt.6005@cortex.ai.toronto.edu"></A>Subject: Re: Random numbers for C: Improvements.Date: 16 Jan 99 04:43:12 GMTFrom: radford@cs.toronto.edu (Radford Neal)Message-ID: &LT;99Jan15.233424edt.6005@cortex.ai.toronto.edu>References: <A HREF = "#QfQn2.10695$bf6.2024@news1.giganews.com">&LT;QfQn2.10695$bf6.2024@news1.giganews.com></A>Newsgroups: sci.math,sci.math.num-analysis,sci.stat.mathLines: 88>Radford Neal wrote in message>&LT;99Jan15.151547edt.785@neuron.ai.toronto.edu>...>>>>I think one needs to face up to an unpleasant truth:  The #define>>facility of C was poorly designed, and is incapable in general of>>supporting the definition of "in-line" procedures.  It is far better>>to simply write ordinary C procedures, and accept the fairly small>>procedure call overhead.In article &LT;QfQn2.10695$bf6.2024@news1.giganews.com>,Jeff Stout &LT;jstout@ncon.com> wrote:>This is not a poor design of the macro facility of C, but a built in>limitation of the C language itself.  The preprocessor is just doing>a stupid text substituation, its the C compiler that is ambigous about>the interpretation>>The C macro language can support "in-line" procedures and a lot>of other junk only true software wienies would ever use.In saying that the #define facility of C was poorly designed, I ofcourse meant that it does not do what is needed to write good programs.The fact that it does stupid text substitation is a big part of this.In the case under discussion, the only reason (I hope!) that obscureand semantically undefined constructs were being used was in order totry to define an in-line procedure using this inadequate facility.Unfortunately, although one can indeed create lots of junk using theC pre-processor, one cannot, in general, use it to create in-lineprocedures.  One can't write a macro equivalent to the following,for instance:  int first_zero (int *a)  { int i;    for (i = 0; a[i]!=0; i++) ;    return i;  }Furthermore, in many cases where one CAN write in-line proceduresusing C macros, 99% of the people who try to do so get it wrong.  Forexample, the following procedure CAN be written as a macro:  void badexample(int a)  {     while (f(a)==0) ;    g(a);  }but NOT as follows:  #define badexample(a) while (f(a)==0) ; g(a);nor as follows:  #define badexample(a) { while (f(a)==0) ; g(a); }The following gets closer:  #define badexample(a) do { while (f(a)==0) ; g(a); } while (0)Note: NO semicolon at the end.  The necessity of this trick is leftas an exercise for the reader.Really, though, one needs to define the macro as follows:  #define badexample(a) do { int fy7653_4xq = a; \                             while (f(fy7653_4xq)==0) ; \                             g(fy7653_4xq); \                        } while (0)Here, fy7853_4xq is assumed to be sufficiently obscure that it isunlikely to conflict with the name of a variable that occurs in a.Not illustrated in this example, but commonly overlooked, is thefrequent necessity to enclose references to the parameters of themacro in parentheses.Failure to understand these arcane necessities will result in macrosthat behave just like the procedure they are trying to mimic around95% of the times they are called, and which produce completely obscurebugs the other 5% of the time.   Radford Neal   <HR><A NAME = "7ogny6htm.fsf@poole.statgen.ncsu.edu"></A>Subject: Re: Random numbers for C: Improvements.Date: 16 Jan 1999 16:14:45 -0500From: zaykin@statgen.ncsu.edu (Dmitri Zaykin)Message-ID: &LT;7ogny6htm.fsf@poole.statgen.ncsu.edu>References: <A HREF = "#QfQn2.10695$bf6.2024@news1.giganews.com">&LT;QfQn2.10695$bf6.2024@news1.giganews.com></A>Newsgroups: sci.math,sci.math.num-analysis,sci.stat.mathLines: 15"Jeff Stout" &LT;jstout@ncon.com> writes:> The C macro language can support "in-line" procedures and a lot> of other junk only true software wienies would ever use.It is probably true that the posted random number generators arebetter implemented as regular functions. C compilers should attempt toinline "short" functions into their callers when certain optimizationflags are enabled.Also, the new C standard will support the "inline" keyword.  Somecompilers (e.g. gcc called without "-ansi" switch) already recognizeit.Dmitri<HR><A NAME = "7pv8f55tf.fsf@poole.statgen.ncsu.edu"></A>Subject: Re: Random numbers for C: Improvements.Date: 16 Jan 1999 15:19:24 -0500From: zaykin@statgen.ncsu.edu (Dmitri Zaykin)Message-ID: &LT;7pv8f55tf.fsf@poole.statgen.ncsu.edu>References: <A HREF = "#99Jan15.151547edt.785@neuron.ai.toronto.edu">&LT;99Jan15.151547edt.785@neuron.ai.toronto.edu></A>Newsgroups: sci.math,sci.math.num-analysis,sci.stat.mathLines: 29

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -