Função Pseudo-Aleatoria rand() Completa

Quem já precisou gerar números aleatórios relativamente grandes em C/C++ se deparou com uma situação no mínimo frustrante.

Como uma implementação de função pseudo-aleatória gera números apenas até 32,767?

Até perceber que a função rand não gerava números com mais de 16 bits, perdi um bom tempo procurando um erro inexistente em meu programa. O pior é que este problema é específico apenas à algumas implementações da stdlib, que pude confirmar ocorrer no Visual Studio e no Mingw, que utiliza uma versão do gcc.

Para gerar números aleatórios até máximo que um inteiro (de 32 bits) agüenta, podemos utilizar o seguinte código (que gera números num intervalo fechado de i até j):

int rand_int(const int i, const int j)
{
    return i + ( ((rand() << 15) | rand()) % (j – i + 1) );
}

O que o código acima faz é gerar dois números aleatórios, deslocar um 15 bits para a esquerda (o primeiro bit em um inteiro deverá ser de sinal) e mesclar os dois num mesmo número de 32 bits. Analogamente, é possível formar números aleatórios de 32, 64, ou quantos mais bits se desejar deslocando distâncias suficientes e combinando todos números em um só.

Mais detalhes sobre implementações e aprimoramentos da função pseudo-aleatória podem ser encontrados neste site. É possível até gerar distribuições razoavelmente distribuídas com alguns truques apenas utilizando a função rand().

Outro detalhe interessante é que a sequência aleatória gerada pela função rand(), ao menos nas implementações em que testei, parece se repetir sempre a cada 2,147,483,648 chamadas. Ou seja, a função é capaz de gerar 231 (cerca de 2 bilhões) números aparentemente aleatórios até que o primeiro número seja gerado novamente e a sequência passada recomece exatamente em mesma ordem. Isto é natural de algorítmos para geração de números aleatórios pois um algorítmo é, por definição, um conjunto de passos específicos e finitos, portanto sempre possuindo uma saída previsível sem espaço para incertezas. Daí os algorítmos serem denominados, na verdade, pseudo-aleatórios, pois obedecem um conjunto de regras complexas, mas finitas, para gerar suas saídas.

Leave a Reply

Your email address will not be published. Required fields are marked *