A biblioteca stdlib define a função rand (abreviatura de random). Esta função gera números aleatórios (ou melhor, pseudoaleatórios). Mais precisamente, cada chamada da função produz um
número aleatório no intervalo fechado [0,RAND_MAX].
A constante RAND_MAX está definida no arquivo-interface stdlib.h.
Eric Roberts (The Art and Science of C) escreveu uma biblioteca random, que torna mais amigável o uso da função rand. Exibiremos abaixo as funções da biblioteca.
int RolaDado (void) { int r; r = rand (); if (r < RAND_MAX / 6) return 1; else if (r < RAND_MAX * 2 / 6) return 2; else if (r < RAND_MAX * 3 / 6) return 3; else if (r < RAND_MAX * 4 / 6) return 4; else if (r < RAND_MAX * 5 / 6) return 5; else return 6; }
char *RolaMoeda (void) { int r; r = rand () % 2; if (r == 1) return "cara"; else return "coroa"; }
Eis como rand pode ser usada para gerar um número real aleatório num dado intervalo:
#include <stdlib.h>
// A função RandomReal devolve um número real
// (pseudo)aleatório no intervalo semi-aberto
// [low, high). O código foi copiado da biblioteca
// random de Eric Roberts.
double RandomReal (double low, double high)
{
double d;
d = (double) rand () / ((double) RAND_MAX + 1);
return low + d * (high - low);
}
Eis como se pode gerar um número inteiro aleatório num dado intervalo:
// A função RandomInteger devolve um inteiro // (pseudo)aleatório entre low e high inclusive, // ou seja, no intervalo fechado [low,high]. // Estamos supondo que high-low <= RAND_MAX. // O código foi copiado da biblioteca random // de Eric Roberts. int RandomInteger (int low, int high) { int k; double d; d = (double) rand () / ((double) RAND_MAX + 1); k = d * (high - low + 1); return low + k; }
Como a função faz o serviço? Primeiro, transforma o número inteiro aleatório produzido por rand em um número real no intervalo [0,1). Depois, transforma esse número real em um número inteiro no intervalo [0,high-low+1). Finalmente, transforma esse número em um inteiro no intervalo [low,high].
Se high – low for maior que RAND_MAX, o função RandomInteger nunca produz o número high. Por exemplo, se RAND_MAX = 99 então
RandomInteger (int 0, int h) ≤ h-1
para todo h > 99.
d = (double) rand () / (RAND_MAX + 1);
Quais as conseqüências?
Qualquer gerador de números pseudoaleatórios, como rand, funciona assim: recebe o número gerado pela chamada anterior do gerador e produz um novo número pseudoaleatório.
O número usado como entrada da primeira execução do gerador é conhecido como semente (= seed). Você pode especificar a semente com a função srand da bilbioteca stdlib.
// A função Randomize inicializa o gerador de números
// (pseudo)aleatórios de modo que os resultados das
// chamadas a RandomInteger e RandomReal sejam
// imprevisíveis. Se essa função não for chamada,
// as outras funções produzirão sempre a mesma
// seqüência de valores.
void Randomize (void)
{
srand ((int) time (NULL));
}
Dada a semente, a seqüência de números produzida pelo gerador está completamente determinada. Se você não especificar a semente, o sistema escolhe uma semente padrão (zero, se não me engano).