Esta dica fala de uma pequena irregularidade que passa desapercebida quando se usa a variável interna "$RANDOM" do
bash para trabalhar com números aleatórios.
A variável interna "$RANDOM" gera aleatórios apenas no intervalo 0 a 32767, que compreende 15 bits, na prática, 2 bytes.
Por ser uma potência de 2, o espaço de probabilidade, quando calcula-se em módulo para outros valores, não é uniforme.
Por exemplo, quero trabalhar com números no espaço amostral de 100 números, 0 a 99 no caso.
Geralmente, o que é feito é algo do tipo:
[$RANDOM%100] (0-99)
Ou então:
[1+($RANDOM%100)] (para 0-100)
Acontece que o número máximo gerado por $RANDOM é 32767, e que 32767 dividido por 100 dá 327, e sobram 67.
67? E daí?
Daí que para ter uma probabilidade uniforme, estaria faltando os números entre 32768 e 32799.
Os números de final 00 a 67 (os restos da divisão por 100) repetem-se 328 vezes no intervalo de 0 a 32767. Os números de final 68 a 99 (os restos da divisão por 100) repetem-se apenas 327 vezes no intervalo de 0 a 32767.
Como não existem os números do intervalo 32768 a 32799, rigorosamente esta probabilidade fica distorcida.
Uma das alternativas possíveis, a que encontrei no momento, seria este cálculo:
Numero = ($RANDOM * "tamanho do intervalo desejado") / 32767
Isto seria um "cálculo de porcentagem". Não é apenas por trabalhar com o número 100.
O valor de $RANDOM representa uma pequena fração no intervalo de 0 a 32767. Fazendo a conta $RANDOM/32767, encontra-se sempre um número entre 0 e 1. Sempre.
Sendo que o bash não trabalha com fracionários, antes desta divisão, multiplica-se pelo valor da faixa com que se quer trabalhar. Seja 10, 20, 50 ou 100, conforme este caso.
* Lembrando que pode ser melhorado.
No caso do valor da faixa ser uma potência de 2, menos que 32768, que 2 elevado à 15, ou um dos seguintes valores:
- 2
- 4
- 8
- 16
- 32
- 64
- 128
- 256
- 512
- 1024
- 2048
- 4096
- 8192
- 16384
- 32768
Então, a probabilidade funciona por igual, apenas calculando-se o resto do valor de $RANDOM por este trabalhar numa faixa de uma potência de 2.
Bem, é isto.