Obteniendo grandes números aleatorios en C/C++
random unsigned-long-long-int (6)
Aquí hay una solución portátil C99 que devuelve un número aleatorio de 64 bits:
unsigned long long llrand() {
unsigned long long r = 0;
for (int i = 0; i < 5; ++i) {
r = (r << 15) | (rand() & 0x7FFF);
}
return r & 0xFFFFFFFFFFFFFFFFULL;
}
Explicación:
rand()
devuelve enteros en el rango de 0 a
RAND_MAX
y
RAND_MAX
solo tiene una garantía de al menos 32,767 (15 bits aleatorios).
long long
tiene 64 bits garantizados, pero puede ser más grande.
La función estándar
rand()
proporciona números que no son lo suficientemente grandes para mí: necesito los
unsigned long long
.
¿Cómo obtenemos números aleatorios realmente grandes?
¡Intenté modificar una función hash simple pero es demasiado
grande
, tarda demasiado en ejecutarse y nunca produce números que sean inferiores a 1e5!
No solicitó un sistema operativo específico y las respuestas aquí son realmente buenas, pero en Linux (y probablemente también en otros sistemas operativos) también puede leer desde un dispositivo aleatorio.
Ejemplo:
#include <stdio.h>
#include <assert.h>
#define RANDDEV "/dev/urandom"
unsigned long long bigrand(void) {
FILE *rdp;
unsigned long long num;
rdp = fopen(RANDDEV, "rb");
assert(rdp);
assert(fread(&num, sizeof(num), 1, rdp) == 1);
fclose(rdp);
return num;
}
Escrito en el móvil, puede tener errores. :PAGS
Puede hacerlo fácilmente con
std::uniform_int_distribution<unsigned long long>
.
Código de ejemplo simple (tomado de
aquí
, modificado para usar
unsigned long long
):
#include <random>
#include <iostream>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<unsigned long long> dis(lowerBorder, upperBorder);
for (int n=0; n<10; ++n)
std::cout << dis(gen) << '' '';
std::cout << ''/n'';
}
Tenga en cuenta que la siembra del mersenne twister como se hace aquí para fines de demostración no es perfecta, por ejemplo, vea here .
Si solo desea generar un valor largo sin signo del valor devuelto por rand () y no le importan las características del resultado, considere la siguiente función que debe ser una versión del compilador y una plataforma independientes (porque no se utilizan "números mágicos"):
// this header has RAND_MAX value
#include <stdlib.h>
// and this header has ULLONG_MAX
#include <limits.h>
unsigned long long ullrand()
// Produces pseudo-random numbers from 0 to ULLONG_MAX
// by filling all bits of unsigned long long integer number
// with bits of several "small" integer numbers generated by rand()
{
unsigned long long myrndnum = 0; // at the beginning just zero
unsigned long long counter = ULLONG_MAX; // at the beginning we have all bits set as 1
// ... and while at least one bit is still set to 1
while(counter > 0) {
myrndnum = (myrndnum * (RAND_MAX + 1)) + rand(); // fill some bits from rand()
counter /= (RAND_MAX + 1); // decrease number of 1-bits in counter
}
// Return the result
return myrndnum;
}
Pero si desea una secuencia de números aleatorios con ciertas características predeterminadas, debe buscar en algunas guías específicas o libros de matemáticas. Por ejemplo, https://www.gnu.org/software/gsl/manual/html_node/Random-number-generator-algorithms.html
También puede usar la biblioteca de impulso (tomada del link ):
#include <ctime> // std::time
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/generator_iterator.hpp>
int main()
{
long long my_min = 1;
long long my_max = 1e5;
boost::mt19937 generator(static_cast<unsigned int>(std::time(0)));
boost::variate_generator<boost::mt19937&, boost::uniform_real<> >
die_gen(generator, boost::uniform_real<> (my_min, my_max));
boost::generator_iterator<boost::variate_generator<boost::mt19937&, boost::uniform_real<> > > die(&die_gen);
std::cout<<"Generated random numbers: /n";
for (int i=0; i <10 ; i++)
{
std::cout<< static_cast<long long>(*die++) << std::endl;
}
return 0;
}
prueba esto:
long N=1000000;
long randNumber;
for(long i=0;i<N;i++)
randNumber=i+rand()