在bash中使用$ RANDOM + $ FLOOR有什么问题?

时间:2014-05-02 19:46:00

标签: bash random

阅读本文:http://www.tldp.org/LDP/abs/html/randomvar.html

#  If you need a random integer greater than a lower bound,
#+ then set up a test to discard all numbers below that.

FLOOR=200

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

   # 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?

我在上次评论中未能对这个问题给出一个合适的答案。这就是我总是用其他语言(C / C ++,Pascal)生成伪随机数的方式,并且没有问题 - 这是否与Bash有关?

3 个答案:

答案 0 :(得分:3)

在编程语言中,随机数生成器可以为您提供高于溢出点的值,后一代码会有一个错误,其中MAXINT - FLOORMAXINT之间的范围内的项会溢出

Bash没有这个错误,但你正在阅读的参考文献显然没有这种意识。

答案 1 :(得分:2)

$RANDOM返回一个随机的16位整数,即范围为032767。我认为评论中的问题假定您只想将下限更改为$FLOOR,但仍然期望上限为32767。如果您使用$RANDOM + $FLOOR,则还会将32967的上限增加,这是预期的。

你可以在没有循环的情况下完成:

number=$(($FLOOR + (($RANDOM*32567)/32767)))

答案 2 :(得分:0)

我不确定ABS看到的问题。这是一个示例测试程序,我在其中选择10到19之间的数字。我使用数组right_way(ABS说的方式)和wrong_way跟踪所选数字(他们说的方式不正确,但不解释原因。:

#! /bin/bash

declare -a right_way
declare -a wrong_way

for count in {1..10000}
do
    #
    # Generating Random Number between 10 and 20
    #
    number=0
    while (( $number < 10 ))
    do
        (( number = $RANDOM % 20 ))
    done
    right_way[$number]=$(( ${right_way[$number]} + 1 ))
    number=$(($RANDOM % 10 + 10 ))
    wrong_way[$number]=$((${wrong_way[$number]} + 1 ))
done

printf "%10s   %10s   %10s\n" "Number" "Right Way" "Wrong Way"
for index in {10..19}
do
    printf "%10d   %10d   %10d\n" $index ${right_way[$index]} ${wrong_way[$index]}
done

结果如下:

    Number    Right Way    Wrong Way
        10         1027         1006
        11         1001          998
        12          996          974
        13          985         1003
        14         1065          991
        15          990          990
        16          959         1063
        17         1023          989
        18          967          988
        19          987          998

我希望平均每个数字的选择大约是1000次,并且两种方法都非常接近。