3

In Advanced Bash-Scripting Guide Chaper 9.3. $RANDOM: generate random integer

It illustrates how to generate a random number greater than a specific number:

FLOOR=200

number=0   #initialize
while [ "$number" -le $FLOOR ]
do
  number=$RANDOM
done
echo "Random number greater than $FLOOR ---  $number"
echo

And then the comment says:

# Let's examine a simple alternative to the above loop, namely
#       let "number = $RANDOM + $FLOOR"
# That would eliminate the while-loop and run faster.
# But, there might be a problem with that. What is it?

I think it is still randomness and greater than $FLOOR, so I don't know what the problem it is.

Vayn
  • 2,507
  • 4
  • 27
  • 33
  • I don't think this is a bash specific question, more a PRNG question. I'm guessing it would impair the quality of the generated random numbers, going to watch this space for a competent answer :) – Torp Apr 07 '11 at 11:14
  • Guess there is a chance that $RANDOM return 0, so the number won't be greater then $FLOOR it would be equal. – Ivan May 18 '23 at 05:55

3 Answers3

1

The problem probably comes from overflow. Let say your prng generate a number between 0 and maxint. If you simply add the floor, what occur when the addition gives a number greater than maxint? Of course, you could simply reject those numbers, but it would result in the same algorithm as the one you proposed.

Depending on what is the floor, some tricks could be used to minimize rejection. For example, if needed number is greater than maxint / 2, you could systematically set the higher bit before testing for rejection.

Charles Brunet
  • 21,797
  • 24
  • 83
  • 124
0

$RANDOM won't ever have a result greater than 32767. However, if you're expecting a result between $FLOOR and 32767, adding $FLOOR and $RANDOM won't help you. If you treat any value greater than 32767 as 32767 then you're making your generator more predictable. Not quite as bad is modding your result by (32767 - $FLOOR) and adding $FLOOR. Another solution without looping is to use $RANDOM * ( 32767 - $FLOOR ) / 32767 + $FLOOR but bash lacks floating point math and may miss a couple numbers due to rounding error.

Matt K
  • 13,370
  • 2
  • 32
  • 51
  • That manual's answer for limiting the range is less random too, although if you're using bash for encryption or something, you're doing it wrong. – Matt K Apr 07 '11 at 13:03
-1

The problem is that you could generate 0 and then your number would be equal to FLOOR.

raul
  • 59
  • 4