I am trying to learn bash so I was working on a "guess the number" type game. I am at the point of trying to generate random numbers based on the user's input for lower and upper bounds. But some test cases seem to create numbers that don't make sense; some being outside my bounds and others not being what I would expect.
Here is my program
echo "Enter the lower bound: "
echo -n "> "
read lowerBound
while [ "$lowerBound" -lt 0 ]
do
echo "Lower bound must be >= 0. Please try again: "
echo -n "> "
read lowerBound
done
echo
echo "Enter the upper bound: "
echo -n "> "
read upperBound
lowerLimit=$(($lowerBound 1))
while [ "$upperBound" -lt "$lowerLimit" ]
do
echo "Upper bound must be larger than lower bound. Please try again: "
echo -n "> "
read upperBound
done
echo
randNum=$(( $RANDOM % ( ($upperBound - $lowerBound) 1 ) ))
echo "RANDOM=$RANDOM randNum=$randNum"
Here is an output that produced unexpected results. I would expect 6: (9237 % (10-1 1) = 7 but output is 5)
Enter the lower bound:
> 1
Enter the upper bound:
> 10
RANDOM=9237 randNum=5
Finally here is some output where the generated number lies outside my bounds. I understand this from doing the math myself, but thought this equation was supposed to generate random numbers in a range. Here 26921 % (126-123 1) = 9237. Most likely just a coincidence that 9237 appeared in subsequent runs.
Enter the lower bound:
> 123
Enter the upper bound:
> 126
RANDOM=26921 randNum=0
I'm not sure if my equation is wrong or if it is something I am doing wrong in Bash. Any pointers would be appreciated.
Note: I am not new to programming, just new to Bash.
CodePudding user response:
Each reference of $RANDOM
generates a new number.
You can see this with something as simple as:
$ echo "$RANDOM : $RANDOM : $RANDOM"
297 : 20330 : 14461
In your code you get one $RANDOM
value when you calculate randNum
, and a second (and likely different) $RANDOM
value in the echo
; net result is randNum=5
was not generated based on $RANDOM=9237
.
If you want to reference the same $RANDOM
value more than once you should first store it in a variable and then (re)use said variable as needed, eg:
ranx=$RANDOM
randNum=$(( $ranx % ( ($upperBound - $lowerBound) 1 ) ))
echo "RANDOM=$ranx randNum=$randNum"