HOWTO · C++
Gerar um número aleatório entre 0 e 1 em C++
Este artigo demonstra como criar um número aleatório entre 0 e 1 intervalo C++
Nesta página
Para gerar um valor pseudoaleatório de ponto flutuante entre 0 e 1, incluindo 0, mas sem incluir 1, combine um mecanismo aleatório do C++11 com std::uniform_real_distribution<double>. O exemplo usa uma semente fixa; assim, o mesmo mecanismo e a mesma semente reproduzem uma sequência em uma determinada implementação. Use <random> em código C++ novo; mantenha std::rand ao dar manutenção a código antigo.
Use C++11 <random> para gerar um número de ponto flutuante
Inclua <random>, crie um mecanismo e passe-o a uma distribuição sempre que precisar de um valor. Um mecanismo gera uma sequência de bits pseudoaleatórios; a distribuição mapeia esses bits para valores do tipo e do intervalo solicitados. Este exemplo completo imprime cinco valores. Como usa uma semente fixa, as execuções repetidas são reproduzíveis na mesma implementação da biblioteca padrão.
#include <iostream>
#include <random>
int main() {
std::mt19937 engine(2026);
std::uniform_real_distribution<double> distribution(0.0, 1.0);
for (int i = 0; i < 5; ++i) {
std::cout << distribution(engine) << '\n';
}
}
Os algarismos impressos dependem da implementação da biblioteca padrão. Em uma mesma implementação, usar o mesmo mecanismo e a mesma semente inicia a mesma sequência. Para obter outra sequência, use uma semente diferente ou inicialize o mecanismo uma única vez com std::random_device; esse dispositivo pode não fornecer entropia não determinística em todos os sistemas.
Entenda o intervalo de saída e escolha um mecanismo
Para std::uniform_real_distribution<double>(0.0, 1.0), o intervalo especificado é semiaberto: 0 pode ser retornado, mas 1 fica de fora. O argumento do modelo seleciona o tipo do resultado de ponto flutuante (float, double ou long double). Uma distribuição precisa receber um mecanismo como argumento; ela não gera valores por conta própria.
O mecanismo determina a sequência pseudoaleatória, e a semente determina onde essa sequência começa. std::mt19937 é um mecanismo padrão bastante usado, com algoritmo especificado. std::default_random_engine é conveniente quando o mecanismo específico não importa, mas sua escolha depende da implementação, por isso é menos adequado quando você precisa da mesma sequência em diferentes bibliotecas padrão. Inicialize o mecanismo uma vez e reutilize-o; semeá-lo novamente antes de cada sorteio pode repetir valores e prejudicar a sequência. Esses recursos são adequados para simulações, jogos e comportamentos aleatórios comuns, mas não para gerar segredos criptográficos.
Use std::rand apenas em código legado
Código antigo pode usar std::rand, declarado em <cstdlib>. Ele retorna um inteiro de 0 até RAND_MAX, inclusive. Converta o valor para ponto flutuante antes de dividi-lo para evitar divisão inteira. Por exemplo, a expressão em linha static_cast<double>(std::rand()) / (static_cast<double>(RAND_MAX) + 1.0) coloca o inteiro no intervalo desejado.
Essa escala mantém o resultado abaixo de 1, inclusive quando std::rand retorna RAND_MAX. Para variar os resultados entre execuções, chame std::srand uma vez antes de gerar valores, muitas vezes usando uma semente baseada no horário; ainda é possível que execuções repetidas usem a mesma semente, e semear o gerador não melhora sua qualidade. RAND_MAX depende da implementação, e std::rand oferece menos controle sobre o mecanismo e a sequência do que <random>. Prefira o mecanismo e a distribuição do C++11 em código novo; use a função legada apenas quando uma interface existente exigir isso.