From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 109d8a,41c51f3b323f0164 X-Google-NewGroupId: yes X-Google-Thread: 107079,4e4830a98c441521,start X-Google-NewGroupId: yes X-Google-Thread: 1014db,41c51f3b323f0164 X-Google-NewGroupId: yes X-Google-Thread: 1094ba,41c51f3b323f0164 X-Google-NewGroupId: yes X-Google-Thread: 101deb,4e4830a98c441521,start X-Google-NewGroupId: yes X-Google-Thread: 103376,4e4830a98c441521,start X-Google-NewGroupId: yes X-Google-Attributes: gid9ef9b79ae9,gid7a498f3897,gid4516fb5702,gid8d3408f8c3,gidbda4de328f,gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news2.google.com!goblin3!goblin.stu.neva.ru!exi-transit.telstra.net!news.telstra.net!exi-spool.telstra.net!exi-reader.telstra.net!not-for-mail From: "robin" Newsgroups: sci.math,sci.math.num-analysis,comp.lang.c,comp.lang.fortran,comp.lang.pl1,comp.lang.ada References: <93b6ca11-f4ae-4598-98f8-9a10be69ca3a@j18g2000yqd.googlegroups.com> Subject: Re: Implementing the KISS4691 RNG Date: Wed, 8 Sep 2010 02:51:50 +1000 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5931 Message-ID: <4c86e93c$0$45651$c30e37c6@exi-reader.telstra.net> NNTP-Posting-Host: 123.3.17.30 X-Trace: 1283909949 exi-reader.telstra.net 45651 123.3.17.30:1042 Xref: g2news1.google.com sci.math:181183 sci.math.num-analysis:14542 comp.lang.c:102628 comp.lang.fortran:27653 comp.lang.pl1:1679 comp.lang.ada:13972 Date: 2010-09-08T02:51:50+10:00 List-Id: "geo" wrote in message news:93b6ca11-f4ae-4598-98f8-9a10be69ca3a@j18g2000yqd.googlegroups.com... | | For those interested in the KISS4691 RNG, I would | like to recommend a final form for the MWC | (Multiply-With-Carry) component, one that provides | a pattern for applications with signed integers, | takes care of the nuisance cases where (x<<13)+c | overflows, and, with different choice of multiplier | and prime but with the same mathematics, permits | going through a full cycle to verify the period. | | First, a simple version for confirming the period: | Here we still have b=2^32, but multiplier a=5 and | prime p=ab-1, for which the order of b mod p is | (p-1)/2 = 5*2^31-1 = 10737418239 | | Note that, as with the full MWC() function below, we | deliberately seek multipliers 'a' of the form 2^i+1 | to ensure the ability to carry out the MWC operations | in mod 2^32 arithmetic. This required a search for primes | of the form (2^i+1)*b^r-1, and I as able to find | the prime (2^13+1)*b^4691-1 for the KISS4691 version. | | But the simpler version with p=(2^2+1)b-1 permits going | through a full cycle (using only 32-bit operations) | in less that a minute. Here we have a function | | f([x,c])=[(5x+c) mod 2^32,trunc((5x+c)/2^32)] | | with inverse | | f^{-1}([x,c])=[trunc((c*2^32+x)/5),(c*2^32+x) mod 5] | | Initial pairs [x,c]=[0,0] or [2^32-1,4] will make the | sequence f([x,c]),f(f([x,c])),f(f(f([x,c]))),... have | period 1. All others, with 0<=x<2^32, 0<=c<5, will have | period (p-1)/2=10737418239 and the (hexed) x's will form, | in reverse order, the hex expansion of j/p for some 0 | int main() | { unsigned long x=123456789,c=3,t; | unsigned long long k; | for(k=0;k<10737418239LL;k++) | {t=(x<<2)+c; | if(t>30)+1; x=t+x;} | else {c=(x>>30); x=t+x; c+=(x>19)+1; t=t+x;} | else {t=t+x; c=(x>>19)+(t>19) by | ((unsigned)x>>19) or ((unsigned)xs>>17) in the XS component.) | | | In case you do not have, or don't want to fetch, the original, | here is the entire listing, with the recommended form for MWC(): | | ------------------------------------------------------------ | static unsigned long xs=521288629,xcng=362436069,Q[4691]; | | unsigned long MWC(void) | {unsigned long t,x; static c=0,j=4691; | j=(j<4690)? j+1:0; | x=Q[j]; t=(x<<13)+c; | if(t>19)+1; t=t+x;} | else {t=t+x; c=(x>>19)+(t>17), xs^=(xs<<5) ) | #define KISS ( MWC()+CNG+XS ) | | #include | int main() | {unsigned long i,x; | for(i=0;i<4691;i++) Q[i]=CNG+XS; | printf("Does MWC result=3740121002 ?\n"); | for(i=0;i<1000000000;i++) x=MWC(); | printf("%27u\n",x); | printf("Does KISS result=2224631993 ?\n"); | for(i=0;i<1000000000;i++) x=KISS; | printf("%27u\n",x); | } | ------------------------------------------------------------ | | Unfortunately, even at the rate of 238 million per second | for MWC(), it would take over 10^40407 years to verify the | period by running through a complete loop. | | George Marsaglia Here is the PL/I version, using 32-bit unsigned arithmetic :- (NOSIZE, NOFOFL): RNG: PROCEDURE OPTIONS (MAIN, REORDER); declare (xs initial (521288629), xcng initial (362436069), Q(0:4690) ) static fixed binary (32) unsigned; MWC: procedure () returns (fixed binary (32) unsigned); declare (t,x,i) fixed binary (32) unsigned; declare (c initial (0), j initial (4691) ) fixed binary (32) unsigned static; if j < hbound(Q,1) then j = j + 1; else j = 0; x = Q(j); t = isll(x,13) + c; if t