HOWTO · C++

Cómo generar un número aleatorio entre 0 y 1 en C++

Este artículo demuestra cómo crear un número aleatorio entre 0 y 1 intervalo C++

En esta página

Para generar un valor pseudoaleatorio de punto flotante desde 0 hasta menos de 1, combina un motor aleatorio de C++11 con std::uniform_real_distribution<double>. El ejemplo usa una semilla fija, por lo que el mismo motor y la misma semilla reproducen una secuencia en una implementación determinada. Usa <random> en código C++ nuevo y reserva std::rand para mantener código antiguo.

Usa <random> de C++11 para generar un número de punto flotante

Incluye <random>, crea un motor y pásaselo a una distribución cada vez que necesites un valor. Un motor genera una secuencia de bits pseudoaleatorios; la distribución transforma esos bits en valores del tipo y el intervalo solicitados. Este ejemplo completo imprime cinco valores. La semilla fija permite reproducirlos al volver a ejecutar el programa con la misma implementación de la biblioteca estándar.

#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';
    }
}

Los dígitos impresos dependen de la implementación de la biblioteca estándar. En una misma implementación, usar el mismo motor y la misma semilla inicia la misma secuencia. Para obtener otra secuencia, usa una semilla distinta o inicializa el motor una sola vez con std::random_device; este dispositivo quizá no proporcione entropía no determinista en todos los sistemas.

Comprende el intervalo de salida y elige un motor

Para std::uniform_real_distribution<double>(0.0, 1.0), el intervalo especificado es semiabierto: puede obtenerse 0, pero se excluye 1. El argumento de plantilla selecciona el tipo de resultado de punto flotante (float, double o long double). Una distribución necesita un motor como argumento; no es un generador independiente.

El motor determina la secuencia pseudoaleatoria y la semilla determina dónde comienza esa secuencia. std::mt19937 es un motor estándar muy usado cuyo algoritmo está especificado. std::default_random_engine resulta práctico cuando el motor concreto no importa, pero su elección depende de la implementación, así que es menos adecuado si necesitas la misma secuencia en distintas bibliotecas estándar. Inicializa el motor una vez y reutilízalo; volver a inicializarlo antes de cada extracción puede repetir valores y perjudicar la secuencia. Estas herramientas sirven para simulaciones, juegos y otros usos aleatorios habituales, pero no para generar secretos criptográficos.

Usa std::rand solo para código heredado

El código antiguo puede usar std::rand, declarado en <cstdlib>. Devuelve un entero entre 0 y RAND_MAX, ambos inclusive. Convierte el valor a punto flotante antes de dividir para evitar la división entera. Por ejemplo, la expresión en línea static_cast<double>(std::rand()) / (static_cast<double>(RAND_MAX) + 1.0) escala el entero al intervalo deseado.

Esta escala mantiene el resultado por debajo de 1, incluso cuando std::rand devuelve RAND_MAX. Para variar los resultados entre ejecuciones, llama a std::srand una sola vez antes de generar valores, a menudo con una semilla basada en la hora; aun así, distintas ejecuciones pueden usar la misma semilla, y sembrar el generador no mejora su calidad. RAND_MAX depende de la implementación, y std::rand ofrece menos control sobre el motor y la secuencia que <random>. Para código nuevo, prefiere el motor y la distribución de C++11; usa la función heredada solo cuando una interfaz existente lo requiera.