kr@asacsg.mh.nl (Koos Remigius) (06/28/90)
Hi there, I have a question about random numbes generators. I have found a random number that gives me a random integer. This function gives me a random integer ( between 0 and range ). ================================================================= function Randomize(range:Integer):Integer; var rawResult:LongInt; { "Raw" random number received from toolbox } begin { Randomize } rawResult:=(ABS(Random); { Get random number between 0 and 32767 } Randomize:=(rawResult * range) div 32768; { Scale to specified range } end; { Randomize } ================================================================= What I need is a random number generator that gives me a random LongInt back. The random number I want must lis between 0 and 2097151. I any of you out there has an idee how to do this, and willing to share your idee, than you can make me verry happy. I' am using Think Pascal for the Macintosh. Greetings from Holland, Koos Remigius. -- Koos Remigius kr@mh.nl via internet backbones Asac Nederland B.V uucp: ..!{uunet,hp4nl}!mh.nl!kr Coencoop 7, 2741 PG Waddinxveen, The Netherlands -------------------- "Still crazy after all this years" ---------------------
russotto@eng.umd.edu (Matthew T. Russotto) (06/29/90)
In article <152@asacsg.mh.nl> kr@asacsg.mh.nl (Koos Remigius) writes: >What I need is a random number generator that gives me a random LongInt back. >The random number I want must lis between 0 and 2097151. >I any of you out there has an idee how to do this, and willing to >share your idee, than you can make me verry happy. >I' am using Think Pascal for the Macintosh. >Greetings from Holland, >Koos Remigius. This may be naive, but why not rndnum,tmp:Longint; rndnum := Random; {get 16 bit random number from toolbox} rndnum := BitShift(rndnum, 16); tmp := Random; {get second 16 bit random number from toolbox} tmp := BitAnd(tmp,65535); {clear sign-extension} rndnum := abs(BitOr(tmp,rndnum)); {put the pieces together} rndnum := rndnum mod 2097152; -- Matthew T. Russotto russotto@eng.umd.edu russotto@wam.umd.edu ][, ][+, ///, ///+, //e, //c, IIGS, //c+ --- Any questions?
kaufman@Neon.Stanford.EDU (Marc T. Kaufman) (06/29/90)
In article <152@asacsg.mh.nl> kr@asacsg.mh.nl (Koos Remigius) writes: >What I need is a random number generator that gives me a random LongInt back. If you have a Mac II, the following might help.: Marc Kaufman (kaufman@Neon.stanford.edu) *** SEG 'Main' ******************************************************************* * ROUTINE Random.a * FUNCTION Provide Minimal-Standard random number generator * CALLING C-compatible calling sequences * * This generator is taken from CACM, October 1988, p.1192 * * It was designed by Stephen K. Park and Keith W. Miller * * For future reference: Possible better multipliers are 48271 and 69621 ******************************************************************* CASE ON MACHINE MC68020 PROC ENTRY MSRandomSeed Start DC.W ' ) Copyright Kaufman Research, 1988 ' MSRandomSeed DC.L 1 ; Place to store seed value ENDPROC ******************************************************************* * ROUTINE MSGetSeed * FUNCTION Return the current seed value * INPUT none * OUTPUT D0 = the seed ******************************************************************* MSGetSeed FUNC EXPORT move.l MSRandomSeed,D0 rts ENDFUNC ******************************************************************* * ROUTINE MSRandom * FUNCTION Return the next random number * INPUT none * OUTPUT D0 = the number ******************************************************************* MSRandom FUNC EXPORT lea MSRandomSeed,A0 move.l (A0),D1 mulu.l #16807,D0:D1 ; long multiply divu.l #$7fffffff,D0:D1 ; modulo 2^31 -1 move.l D0,(A0) rts ENDFUNC ******************************************************************* * ROUTINE MSRanSet * FUNCTION Set the random number seed * INPUT The seed value * OUTPUT The seed value ******************************************************************* MSRanSet FUNC EXPORT move.l 4(A7),D0 ; the value the user wants to use and.l #$7fffffff,D0 beq.s MSGetSeed ; zero is not a valid value cmp.l #$7fffffff,D0 beq.s MSGetSeed ; neither is 2^31-1 lea MSRandomSeed,A0 move.l D0,(A0) rts ENDFUNC END
davidd@ttidca.TTI.COM (David Dantowitz) (06/30/90)
Be quite careful how you splice together random numbers to form larger random numbers. Linear-conguential random number generators (of the form: seed = seed*a mod m + b) have more "random" high order bits than low order bits. Appending two 16 bit numbers may skew your application in a way that's difficult to measure. If you want a 32 bit random number then check out Knuth for some multipliers (a) and modulos (m) that will give you "good" random numbers. Sorry I don't have it handy. -- David Dantowitz Singing Barbershop when not computing
kaufman@Neon.Stanford.EDU (Marc T. Kaufman) (07/01/90)
In article <1990Jun29.020739.9146@Neon.Stanford.EDU> kaufman@Neon.Stanford.EDU (Marc T. Kaufman) writes: >In article <152@asacsg.mh.nl> kr@asacsg.mh.nl (Koos Remigius) writes: ->What I need is a random number generator that gives me a random LongInt back. and I write back: >If you have a Mac II, the following might help.: [some assembly code for the Mac deleted] I recently received the following mail: "You may like to know that the Random function in the Mac ROM *is* the same as the "minimal std" function published in the CACM paper. It's just that it truncates the computed result to 16-bits. However, you can get at the 32-bit result by accessing the QD global "RandSeed". This works because Random uses the linear congruential method which is iterative, and saves the next computed random no in the sequence in RandSeed. Ie do something like (in C) (void) Random(); /* ignore 16 bit result */ theValue = qd.randSeed; /* use 32-bit result */ In Pascal, just assign the unwanted 16-bit result to a dummy. I compared 10000 rn's from a C version of the CACM rn generator with that generated by the ROM's Random() function, and they were identical. Best regards Sak Wathanasin Network Analysis Limited uucp: ...!ukc!nan!sw other: sw@network-analysis-ltd.co.uk phone: (+44) 203 419996 telex: 9312130355 (SW G) snail: 178 Wainbody Ave South, Coventry CV3 6BX, UK I thank Sak for this info. I am not sure just which Macs this applies to -- probably the ci and fx, certainly not the SE. Can someone from Apple tell us when the algorithm changed, and is it part of a system patch so all Macs can benefit from it? Marc Kaufman (kaufman@Neon.stanford.edu)
nolan@tssi.UUCP (Michael Nolan) (07/04/90)
It's fairly easy to write a random number generator, and there are several in Knuth's "Art of Computer Programming", I *think* in volume 2, at any rate the subject matter of the correct volume is algorithms. One I've used many times involves three relatively prime numbers n1, n2, and n3. (Relatively prime means these numbers have no common factors above 1.) Please pardon my pseudocode: This_Random_Number = (Previous_Random_Number * n1 + n2) mod n3. Of course, you need to provide an initial Previous_Random_Number as a seed. This will generate a random number sequence of period n3. I assume this will work in longints. ------------------------------------------------------------------------------ Mike Nolan "I don't know what apathy is, Tailored Software Services, Inc. and I don't want to find out!" Lincoln, Nebraska (402) 423-1490 UUCP: tssi!nolan should work, if not try something like uunet!frith!upba!tssi!nolan
alexr@ucscb.ucsc.edu (Alexander M. Rosenberg) (07/06/90)
In article <1990Jun30.170949.1426@Neon.Stanford.EDU> kaufman@Neon.Stanford.EDU (Marc T. Kaufman) writes: > I thank Sak for this info. I am not sure just which Macs this applies to -- > probably the ci and fx, certainly not the SE. Can someone from Apple tell us > when the algorithm changed, and is it part of a system patch so all Macs can > benefit from it? > > Marc Kaufman (kaufman@Neon.stanford.edu) Sak is incorrect. While he may note that the algorithm is the same (I'm not sure), it is definately not probable for him to have matched up 10000 numbers. Apple's random number generator uses the tick count as a seed upon each InitGraf (I may be wrong here, but I'm sure that it is time derived.) I do know that the mouse driver has always kept track of the time at which a click occurs, and takes the difference in time between that click and the previous one, and adds this number to the current randSeed. This is where an additional level of randomness is provided. (Humans tend to be more "random" than computers do, eh?) This is why you may have seen results that didn't follow a pattern. (It is possible that in 32-bit QuickDraw they changed the algorithm, but I seriously doubt it.) (ignore any paths found here, they are incorrect. I can be reached at Alex_Rosenberg.INTEGRATION@gateway.qm.apple.com) --------------------------------------------------------------------------- - Alexander M. Rosenberg - INTERNET: alexr@ucscb.ucsc.edu - Yoyodyne - - 330 1/2 Waverley St. - UUCP:ucbvax!ucscc!ucscb!alexr - Propulsion - - Palo Alto, CA 94301 - BITNET:alexr%ucscb@ucscc.BITNET- Systems - - (415) 329-8463 - Nobody is my employer so - :-) - - - so nobody cares what I say. - -
alexr@ucscb.ucsc.edu (Alexander M. Rosenberg) (07/06/90)
In article <8999@goofy.Apple.COM> alexr@ucscb.ucsc.edu (Alexander M. Rosenberg) writes: > Apple's random number generator uses the tick count as a seed upon each > InitGraf (I may be wrong here, but I'm sure that it is time derived.) I do > know that the mouse driver has always kept track of the time at which a > click occurs, and takes the difference in time between that click and the > previous one, and adds this number to the current randSeed. This is where > an additional level of randomness is provided. (Humans tend to be more > "random" than computers do, eh?) <SNIVELING WIMP MODE ON> Just to protect my sanity, I checked. The standard ADB mouse driver does the aforementioned random seed changes, to a low memory global, RndSeed ($156). InitGraf does use 1 as a seed. (a silly seed). Under Random, they suggest using RndSeed (the low-memory global) as a seed. I suspect that something in the system must use this as a seed. I was working from memory. Oops. Alex P.S. I'm sure that pre-ADB mouse driver code does the same thing. --------------------------------------------------------------------------- - Alexander M. Rosenberg - INTERNET: alexr@ucscb.ucsc.edu - Yoyodyne - - 330 1/2 Waverley St. - UUCP:ucbvax!ucscc!ucscb!alexr - Propulsion - - Palo Alto, CA 94301 - BITNET:alexr%ucscb@ucscc.BITNET- Systems - - (415) 329-8463 - Nobody is my employer so - :-) - - - so nobody cares what I say. - -
shahn@hstbme.mit.edu (Samuel Hahn) (07/07/90)
This may be a bit obvious but why don't you just generate a long number one character at a time? For instance to go between 0 and 999999999999 just pick each digit from random() mod 9? This won't be very fast but it should work if you are willing to accept the limitations of the built in random number generator... It also gets a bit trickier if you want numbers between 0 and say 945832427, but it could still be done with a bunch of conditional statements. Sam Hahn
vladimir@prosper (Vladimir G. Ivanovic) (07/07/90)
The June 1988 (v31 #6) issue of the Communications of the ACM has an article by Pierre L'Ecuyer called, "Efficient and Portable Combined Random Number Generators". The following October (v31 #10), Stephen Park and Keith Miller published "Random Number Generators: Good Ones are Hard to Find." Both articles are ESSENTIAL reading for anyone interested in random number generation, and this includes naive users. The conclusion of both articles is that horrible random (sic) number generators are used by people who don't know better, while very good ones take less than 20 lines of Pascal! Amoung the horrid generators are some that come with certain systems or are presented in textbooks! Here are the two proposed random number generators. Even though I have proof read them twice, I made no guarantees whatsoever about the correctness or the usablilty of the code below. Here is the Minimal Standard proposed by Park and Miller: function Random : real; { Initialize seed with 1..2147483646 } { maxint must be greater than 2**31 -1 } const a = 16807; m = 2147483647; q = 12773; { m div a } r = 2836; { m mod a } var lo, hi, test : integer; begin hi := seed div q; lo := seed mod q; test := a * lo - r * hi; if test > 0 then seed := test else seed := test + m; Random := seed / m end; Here is the Portable Combined Generator of Ecuyer for 32-bit computers. It has a period of roughly 8.12544 x 10**12. Function Uniform : real; { Initialize s1 to 1..2147483562; s2 to 1..2147483398 } var Z, k : integer; begin k := s1 div 53668; s1 := 40014 * (s1 - k * 53668) - k * 12211; if s1 < 0 then s1 := s1 + 2147483563; k := s2 div 52774; s2 := 40692 * (s2 - k * 52774) - k * 3791; if s2 < 0 then s2 := s2 + 2147483399; Z := s1 - s2; if Z < 1 then Z := Z + 2147483562; Uniform := Z * 4.656613e-10; end; All are urged to read both articles for a much better presentation. And you don't have to be a mathematician to understand them: very little of either article is not accessible to a competent programmer. Enjoy! -- Vladimir