When either rand() or randRange() is used for the first time in a request, a
random number generator is instantiated using the value of getTickCount() as
the seed.  This same random number generator is used for all rand(),
randRange(), and randomize() calls for the remainder of the request.

So, randomize() does affect both rand() and randRange().

To prove it, see this code:

<cfoutput>

   <cfloop index="i" from="1" to="10">
      <code>#randRange(1, 9)#</code><br />
   </cfloop>   
   
   <hr />
   
   <cfset randomize(1)>      

   <cfloop index="i" from="1" to="10">
      <code>#randRange(1, 9)#</code><br />
   </cfloop>   
   
</cfoutput>

The code calls randomize with a fixed seed.  As a result, the results from
randRange are completely predictable and are the same with each request.

I'm not sure why the docs say to use randomize() before rand() but not
randRange(), or really why they say to use randomize() at all since the
standard methodlogy is to call it with some derivative of getTickCount() as
the argument and the original getTickCount() is how the generator is created
in the first place.

In fact, I've found better results by not calling randomize() at all.  The
issue is you can't actually pass getTickCount() to randomize() because
randomize() only accepts a java int, but in reality the underlying random
number generator uses a java long so while CF can internally pass
getTickCount() directly to randomize() we CF'ers can not.  

One first reaction would be to just divide getTickCount() by a number to
reduce the value to within the allowable limits.  Given the following code:

<cfoutput>

   <cfloop index="i" from="1" to="10">
      <code>#rand()#</code><br />
   </cfloop>   
   
   <hr />
   
   <cfset randomize(getTickCount()/1000)>      

   <cfloop index="i" from="1" to="10">
      <code>#rand()#</code><br />
   </cfloop>   
   
</cfoutput>

The numbers on top of the line are random across requests whereas below the
line will repeat if you refresh quickly.  So instead you can use this code:

<cfoutput>

   <cfloop index="i" from="1" to="10">
      <code>#rand()#</code><br />
   </cfloop>   
   
   <hr />
   
   <cfset randomize(right(getTickCount(), 9))>      

   <cfloop index="i" from="1" to="10">
      <code>#rand()#</code><br />
   </cfloop>   
   
</cfoutput>

Which will give you more random numbers than using getTickCount()/1000 but
still less random than leaving the default.

Perhaps you can get more random numbers by creating an instance of
java.util.Random and storing it in the application scope so you're using the
same generator across requests instead of a new one seeded at the beginning
of each request.  Maybe someone with more Java experience can confirm or
refute this possibility.

HTH,

Sam

-----------------------------------------------
Blog: http://www.rewindlife.com
Charts: http://www.blinex.com/products/charting
-----------------------------------------------

> -----Original Message-----
> From: Tony Weeg [mailto:[EMAIL PROTECTED]
> Sent: Friday, January 23, 2004 3:24 PM
> To: CF-Talk
> Subject: randomize()
>
> does randomize do anything for randRange(), or ONLY for rand()
>
> thanks.
>
> ...tony
>
[Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings]

Reply via email to