Geração de Números Pseudoaleatórios em C

Compreendendo a Geração de Números Aleatórios em C

No contexto da ciência da computação, a geração de números é frequentemente referida como pseudoaleatória. Isso implica que, apesar de os números produzidos exibirem características de aleatoriedade, eles são, na verdade, produto de um algoritmo determinístico. Consequentemente, se o ponto de partida (ou "semente") for o mesmo, o algoritmo reproduzirá a idêntica sequência de números a cada execução.

A Função rand(): O Mecanismo Básico

A biblioteca padrão C, especificamente <stdlib.h>, oferece a função rand() para a produção de números pseudoaleatórios. Por padrão, rand() gera um inteiro dentro do intervalo de 0 até RAND_MAX, uma constante que também é definida em <stdlib.h> e que tipicamente possui o valor de 32767 ou superior.

Sem uma semente inicial definida, invocações sucessivas de rand() resultam na mesma sequência numérica a cada vez que o programa é executado. Considere o exemplo a seguir:

#include <stdio.h>  // Inclui printf
#include <stdlib.h> // Inclui rand

int main() {
    printf("Resultados sem inicialização da semente:\n");
    for (int i = 0; i < 3; i++) {
        int numeroGerado = rand();
        printf("Iteração %d: %d\n", i + 1, numeroGerado);
    }
    return 0;
}

Ao compilar e executar o código acima múltiplas vezes, você observará que os números impresos permanecerão idênticos em todas as execuções, ilustrando a natureza determinística do gerador sem uma semente.

Inicializando a Semente com srand()

Para que a sequência de números pseudoaleatórios varie a cada execução do programa, é crucial inicializar o gerador. Esta tarefa é realizada pela função srand(), que também é parte de <stdlib.h>. A função srand() aceita um argumento do tipo inteiro sem sinal (unsigned int), que funciona como a semente.

O desafio reside em prover uma semente que seja diferente a cada vez que o programa é iniciado. Uma estratégia comum é empregar o tempo atual do sistema, que está em constante progressão. A função time(), encontrada em <time.h>, pode ser utilizada para obter um valor baseado na hora corrente.

A chamada time(NULL) retorna o número de segundos transcorridos desde a "Epoch" (00:00:00 UTC de 1º de janeiro de 1970). Como este valor é sempre único e crescente, ele se mostra uma semente eficaz. É importante realizar um cast explícito do tipo de retorno de time() (que é time_t) para unsigned int, para garantir compatibilidade com srand().

#include <stdio.h>  // Inclui printf
#include <stdlib.h> // Inclui rand, srand
#include <time.h>   // Inclui time

int main() {
    // Semeia o gerador de números aleatórios utilizando a hora atual do sistema
    srand((unsigned int)time(NULL));

    printf("Resultados com semente dinâmica (baseada no tempo):\n");
    for (int i = 0; i < 3; i++) {
        int numeroDinamico = rand();
        printf("Iteração %d: %d\n", i + 1, numeroDinamico);
    }
    return 0;
}

Com a inclusão dessa semente dinâmica, o programa produzirá uma sequência distinta de números pseudoaleatórios a cada execução, dada a variação da semente baseada no tempo.

Gerando Números em um Intervalo Específico

Muitas vezes, a necessidade é gerar números aleatórios dentro de um intervalo bem definido [min, max], em vez de 0 a RAND_MAX. Para isso, podemos empregar o operador módulo (%) em conjunto com operações aritméticas para ajustar o resultado de rand() ao interavlo desejado.

A fórmula genérica para gerar um número aleatório N, tal que min ≤ N ≤ max, é:

N = rand() % (max - min + 1) + min;

Vamos exemplificar com a geração de números aleatórios inteiros no intervalo de 101 a 200 (inclusive):

  • O valor min seria 101.
  • O valor max seria 200.
  • A expressão (max - min + 1) resultaria em (200 - 101 + 1) = 100.

Assim, a expressão para o cálculo seria rand() % 100 + 101. O operador % 100 limita o resultado de rand() a um intervalo de 0 a 99. A adição de 101 a este resultado desloca o intervalo para 101 a 200.

#include <stdio.h>  // Inclui printf
#include <stdlib.h> // Inclui rand, srand
#include <time.h>   // Inclui time

int main() {
    // Semeia o gerador de números aleatórios uma única vez
    srand((unsigned int)time(NULL));

    int limiteInferior = 101;
    int limiteSuperior = 200;

    printf("Números aleatórios no intervalo [%d, %d]:\n", limiteInferior, limiteSuperior);
    for (int i = 0; i < 3; i++) {
        // Gera um número no intervalo especificado
        int numeroNoIntervalo = rand() % (limiteSuperior - limiteInferior + 1) + limiteInferior;
        printf("Iteração %d: %d\n", i + 1, numeroNoIntervalo);
    }
    return 0;
}

Este método é fundamantal para uma vasta gama de aplicações que requerem aleatoriedade dentro de limites bem definidos, como em simulações, desenvolvimento de jogos ou criação de dados de teste.

Tags: C_language random_numbers pseudo_random stdlib.h time.h

Publicado em 7-15 08:45