On May 5, Collin Rogowski said:

>rand(123 - 48) + 48:

I am glad you used this construct (and even moreso that you explained the
mathematics and logic used therein).  I have dealt with programmers who
used to write simple mIRC scripts, and expect

  rand(10, 30);

to return a number from 10 to 30.  Much to their chagrin, this code is
seen by Perl as

  rand(30);

because of the way the , operator works in scalar context (for more on
context, please read http://www.pobox.com/~japhy/articles/pm/2000-02.html
"List is a Four-Letter Word").

Even "worse", rand(EXPR) returns a real number greater than or equal to 0
and less than EXPR

  0 <= x < EXPR

So technically, rand(10,30), if it "worked", would return something

  10 <= x < 30

This is usually not the desired case.  So, using rather simple math, we
can construct the desired result.

First, though, you have to see how rand(x+y) and rand(x)+y produce VERY
different results:

  0 <= rand(x + y) < x + y
  y <= rand(x) + y < x + y

Ok, now to the gooey stuff:

  to get a random number from A to B (which can be A or B)
  i.e. randBound(5,15) = 5, 6, 7, ..., 13, 14, or 15

  0 <= rand(B) + 0  < B + 0
  A <= rand(B) + A  < B + A

  5 <= rand(B) + 5  < B + A
  5 <= rand(10) + 5 < 15
  5 <= rand(11) + 5 < 16

So we get to:

  5 <= rand(15 + 1 - 5) + 5 < 16

which, if $a = 5 and $b = 15, is:

  rand($b + 1 - $a) + $a;

to return a number $x such that

  $a <= $x < $b+1

And when we take the integer value of this value, it will be

  $a <= $x <= $b

So there we are.  Now for our function.

  sub randBound {
    my ($lower, $upper) = @_;
    return int( rand($upper + 1 - $lower) + $lower );
  }

-- 
Jeff "japhy" Pinyan      [EMAIL PROTECTED]      http://www.pobox.com/~japhy/
Are you a Monk?  http://www.perlmonks.com/     http://forums.perlguru.com/
Perl Programmer at RiskMetrics Group, Inc.     http://www.riskmetrics.com/
Acacia Fraternity, Rensselaer Chapter.         Brother #734


Reply via email to