HOWTO · C++
Cómo generar un número flotante aleatorio en C++
Este artículo demuestra cómo generar un número flotante aleatorio en C++
En esta página
Usa la biblioteca <random> de C++11 para generar un valor pseudoaleatorio de coma flotante dentro de un rango elegido. std::uniform_real_distribution recibe los límites inferior y superior, mientras que un motor aleatorio proporciona la secuencia. Elige float o double según la precisión que necesite tu aplicación; reserva rand para mantener código heredado.
Generar un valor aleatorio de coma flotante con C++11
Este programa completo genera cinco valores en el intervalo semiabierto [10, 100). La semilla fija hace que la secuencia del motor se repita con la misma implementación de la biblioteca estándar, lo que resulta útil durante la depuración. Los valores impresos exactos pueden variar entre implementaciones, porque el estándar no especifica un algoritmo de distribución que produzca una secuencia portátil.
Ejecuta este ejemplo:
#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
El argumento de plantilla de la distribución determina el tipo del resultado. De forma predeterminada es double; los tipos admitidos por el estándar son float, double y long double. Elige uno explícitamente para que el tipo quede claro en el punto de llamada: el ejemplo usa double, mientras que std::uniform_real_distribution<float> solicita valores float. Los límites son valores reales y la distribución excluye el límite superior. Este intervalo semiabierto resulta útil para escalar valores a rangos en los que incluir el extremo superior exacto podría solaparse con el siguiente intervalo. Por ejemplo, el rango de 0.0 a 1.0 puede representar una proporción normalizada, mientras que el de 10.0 a 100.0 puede representar una medición en las unidades elegidas.
Usa float cuando su precisión sea suficiente y sea importante ahorrar almacenamiento o ancho de banda; elige double para obtener un equilibrio habitual entre precisión y rango. long double está disponible cuando resulta útil contar con precisión adicional, aunque cuánto aporta depende de la implementación. Siempre que sea práctico, mantén los valores de los límites alineados con el tipo de la distribución, sobre todo al cambiar el argumento de plantilla, para que el rango previsto sea fácil de comprobar. La distribución no garantiza la misma secuencia impresa en distintas implementaciones de la biblioteca estándar, aunque la semilla del motor sea fija.
Mantén el motor activo y reutilízalo para generar una secuencia. Crear un motor nuevo con una semilla nueva para cada valor puede reiniciar o degradar la secuencia. Para obtener resultados repetibles, usa una semilla fija, como en el ejemplo. Para obtener una secuencia distinta en cada ejecución, std::random_device puede proporcionar material para la semilla si la implementación admite una salida no determinista; esto no está garantizado en todos los sistemas. Ninguna de estas opciones convierte este generador pseudoaleatorio de uso general en una opción adecuada para valores sensibles desde el punto de vista de la seguridad. La semilla inicializa el motor una vez; no sirve para pedir un motor independiente nuevo en cada generación. Si la aplicación necesita resultados reproducibles entre ejecuciones, registra la semilla junto con las demás entradas. Si necesita tokens seguros, usa una fuente criptográfica de números aleatorios en lugar de esta distribución y este motor.
Usar rand como alternativa heredada limitada
La función rand() de la biblioteca C devuelve un entero pseudoaleatorio desde 0 hasta RAND_MAX, inclusive; el valor de RAND_MAX depende de la implementación. Para convertirlo a un rango de coma flotante, divide por RAND_MAX usando aritmética de coma flotante antes de escalar el resultado. Este ejemplo produce valores en [10, 100], incluido el límite superior cuando rand() devuelve 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() tiene un estado y una calidad estadística limitados. Una semilla fija hace que este ejemplo sea repetible con la misma implementación de la biblioteca C, pero no lo vuelve impredecible ni seguro. Para el código C++ nuevo, prefiere <random>: separa el motor de la distribución y permite elegir directamente el tipo del resultado y el rango.