HOWTO · C++
Como gerar um número de ponto flutuante aleatório em C++
Este artigo demonstra como gerar um número de ponto flutuante aleatório em C++.
Nesta página
Use a biblioteca <random> do C++11 para gerar um valor pseudoaleatório de ponto flutuante dentro de um intervalo escolhido. std::uniform_real_distribution recebe os limites inferior e superior, enquanto um mecanismo aleatório fornece a sequência. Use float ou double conforme a precisão necessária para sua aplicação; use rand apenas ao manter código legado.
Gere um valor de ponto flutuante aleatório com C++11
Este programa completo gera cinco valores no intervalo semiaberto [10, 100). A semente fixa torna a sequência do mecanismo repetível com a mesma implementação da biblioteca padrão, o que é útil durante a depuração. Os valores impressos exatos podem variar entre implementações, pois o algoritmo da distribuição não é especificado de modo a produzir uma sequência portátil.
Execute este exemplo:
#include <iomanip>
#include <iostream>
#include <random>
int main() {
std::mt19937 engine(2026);
std::uniform_real_distribution<double> distribution(10.0, 100.0);
for (int i = 0; i < 5; ++i) {
std::cout << std::setprecision(10) << distribution(engine) << '\n';
}
}
78.99481399
96.50696843
96.65823206
73.63312607
11.77415091
O argumento de modelo da distribuição seleciona o tipo do resultado. O padrão é double; os tipos aceitos pela biblioteca padrão são float, double e long double. Escolha um explicitamente para deixar o tipo claro no ponto de chamada: o exemplo usa double, enquanto std::uniform_real_distribution<float> solicita valores float. Os limites são valores reais, e a distribuição exclui o limite superior. Esse intervalo semiaberto é útil para escalar valores em faixas nas quais incluir o limite superior exato faria o valor coincidir com o início da faixa seguinte. Por exemplo, o intervalo de 0.0 a 1.0 pode representar uma proporção normalizada, enquanto o intervalo de 10.0 a 100.0 pode representar uma medida nas unidades escolhidas.
Use float quando sua precisão for suficiente e o uso de armazenamento ou largura de banda for importante; escolha double para obter o equilíbrio habitual entre precisão e faixa de valores. long double está disponível quando sua precisão adicional for útil, embora o ganho dependa da implementação. Sempre que possível, mantenha os valores dos limites alinhados ao tipo da distribuição, especialmente ao alterar o argumento de modelo, para que a faixa pretendida seja fácil de verificar. A distribuição não garante a mesma sequência impressa entre diferentes implementações da biblioteca padrão, mesmo quando a semente do mecanismo é fixa.
Mantenha o mecanismo ativo e reutilize-o ao gerar uma sequência. Criar um mecanismo com uma nova semente para cada valor pode reiniciar ou prejudicar a sequência. Para obter resultados repetíveis, use uma semente fixa, como acima. Para obter uma sequência diferente a cada execução, std::random_device pode fornecer material para a semente quando a implementação oferecer saída não determinística; esse comportamento não é garantido em todos os sistemas. Nenhuma dessas opções torna esse gerador pseudoaleatório de uso geral adequado para valores sensíveis à segurança. A semente inicializa o mecanismo uma vez; ela não serve para criar um mecanismo independente a cada sorteio. Se a aplicação precisar reproduzir resultados entre execuções, registre a semente junto com as outras entradas. Para gerar tokens sensíveis à segurança, use uma fonte criptográfica de números aleatórios em vez desta distribuição e deste mecanismo.
Use rand como uma alternativa legada limitada
A função rand() da biblioteca C retorna um inteiro pseudoaleatório entre 0 e RAND_MAX, inclusive; o valor de RAND_MAX depende da implementação. Para convertê-lo em um intervalo de ponto flutuante, divida por RAND_MAX usando aritmética de ponto flutuante antes de aplicar a escala. Este exemplo mapeia os valores para [10, 100], incluindo o limite superior quando rand() retorna RAND_MAX:
#include <cstdlib>
#include <iostream>
int main() {
const double lower = 10.0;
const double upper = 100.0;
std::srand(2026);
for (int i = 0; i < 5; ++i) {
const double value = lower + (upper - lower) *
(static_cast<double>(std::rand()) / RAND_MAX);
std::cout << value << '\n';
}
}
60.2772
88.4741
67.8989
11.5099
83.7273
rand() tem estado e qualidade estatística limitados; uma semente fixa torna este exemplo repetível na mesma implementação da biblioteca C, mas não o torna imprevisível nem seguro. Prefira <random> em código C++ novo, pois essa biblioteca separa o mecanismo da distribuição e permite escolher diretamente o tipo do resultado e o intervalo.