This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

Random numbers (srand)

Old posts that have not been replied to for several years.
Locked
m
malone

Post by malone »

Im pretty new to tcl and Im having a few problems with random numbers. What Ive got at the moment is

putserv "PRIVMSG $chan :...[lindex $response_array [rand [llength $response_array]]]"

Which works, and gives a fairly random set of responses. But its seems to pick some answers a lot more often than others, and some it misses out entirely.

In other languages Ive used you have to seed the random number generator before using it. But I cant seem to do that in my scripts.

srand [clock clicks]

gives this error

Tcl error [do_response_chan]: invalid command name "srand"

even tho srand seems to be in the tcl manual. Any ideas what Im doing wrong? Do I need to the seed the generator, or am i just being paranoid?
User avatar
stdragon
Owner
Posts: 959
Joined: Sun Sep 23, 2001 8:00 pm
Contact:

Post by stdragon »

First, rand is an eggdrop function, not a tcl function, so seeding the tcl rand generator won't do much good. Anyway, tcl's rand function is seeded automatically by tcl. (Use [expr rand()] to get a random number from it.)

Second, the eggdrop rand generator is already seeded. It's probably just a crappy algorithm.

You could try using tcl's instead, or you could use the md5 function to create pseudo-random numbers.

Code: Select all

set _last_rand [clock seconds]

proc md5rand {len} {
  global _last_rand
  set r [md5 "[clock seconds] $_last_rand"]
  set _last_rand $r
  set x1 [string range $r 0 7]
  set x2 [string range $r 8 15]
  set x3 [string range $r 16 23]
  set x4 [string range $r 24 31]
  scan "$x1 $x2 $x3 $x4" "%x %x %x %x" i1 i2 i3 i4
  return [expr ($i1 + $i2 + $i3 + $i4) % $len]
}
I did a little test to see the randomness of this vs. rand:

.tcl for {set i 0} {$i < 100} {incr i} {lappend md5rands [md5rand 10]}

.tcl for {set i 0} {$i < 100} {incr i} {lappend rands [rand 10]}

.tcl for {set i 0} {$i < 100} {incr i} {lappend tclrands [expr round(rand() * 1000000) % 10]}

.tcl putlog [lsort $tclrands]


.tcl putlog [lsort $md5rands]
[13:59] 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9

.tcl putlog [lsort $rands]
[13:59] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 2 2 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9

.tcl putlog [lsort $tclrands]
[13:59] 0 0 0 0 0 0 0 0 0 0 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 9

To be perfectly distributed, each number should appear 10 times. In md5rand, the most deviant waa 8 (appeared 14 times). For rand, the most deviant was 2 (appeared 2 times). For tclrand, the most deviant was 1 (appeared 4 times). You'd have to compute more statistics to really tell, but it looks like md5rand is superior.
Locked