"este número debería verse como xxxxx, yyyyy". Cómo generar dobles aleatorios y cómo formatear dobles como cadenas son cuestiones completamente independientes.
Steve Jessop
Y ahora que lo pienso de manera alternativa: generar dobles distribuidos uniformemente y generar decimales distribuidos uniformemente son tareas algo diferentes, aunque relacionadas.
Steve Jessop
La generación de enteros distribuidos uniformemente está más estrechamente relacionada con el problema de los decimales.
Potatoswatter
Respuestas:
116
Así es cómo
doublefRand(double fMin, double fMax){
double f = (double)rand() / RAND_MAX;
return fMin + f * (fMax - fMin);
}
Recuerde llamar a srand () con una semilla adecuada cada vez que se inicie su programa.
[Editar] Esta respuesta es obsoleta ya que C ++ obtuvo su biblioteca aleatoria nativa no basada en C (vea la respuesta de Alessandro Jacopson) Pero, esto todavía se aplica a C
Si agrega 1 a RAND_MAX, hágalo con cuidado, ya que podría ser igual a INT_MAX. double f = rand() / (RAND_MAX + 1.0);
Steve Jessop
8
Tenga en cuenta que la aleatoriedad de esto puede ser limitada. El rango xxxxx, yyyyy sugiere 10 dígitos decimales. Hay muchos sistemas en los que RAND_MAX es menor que 10 ^ 10. Esto significaría que algunos números en ese rango tienenp(xxxxx,yyyyy)==0.0
MSalters
7
Debe evitar rand () si es posible. Vea la otra respuesta para una solución C ++ 11 o TR1.
jfritz42
No todo el mundo usa C ++ 0x, tr1 o C ++ 11 ¿Hay alguna referencia que muestre que debe evitarse rand ()? Ha sido la única forma de obtener números aleatorios durante décadas.
Si la precisión es un problema aquí, puede crear números aleatorios con una graduación más fina aleatorizando los bits significativos. Supongamos que queremos tener un doble entre 0.0 y 1000.0.
En MSVC (12 / Win32) RAND_MAX es 32767, por ejemplo.
Si usa el rand()/RAND_MAXesquema común , sus brechas serán tan grandes como
1.0 / 32767.0 * ( 1000.0 - 0.0) = 0.0305 ...
En el caso de IEE 754 variables dobles (53 bits significativos) y aleatorización de 53 bits, la brecha de aleatorización más pequeña posible para el problema de 0 a 1000 será
2^-53 * (1000.0 - 0.0) = 1.110e-13
y por lo tanto significativamente más bajo.
La desventaja es que se necesitarán 4 llamadas rand () para obtener el número entero aleatorio (asumiendo un RNG de 15 bits).
Nota: No sé si el número de bits para unsigned long long (64 bits) es mayor que el número de bits de doble mantisa (53 bits para IEE 754) en todas las plataformas o no. Probablemente sería "inteligente" incluir un cheque como if (sizeof(unsigned long long)*8 > num_mant_bits) ...si este no fuera el caso.
Respuestas:
Así es cómo
double fRand(double fMin, double fMax) { double f = (double)rand() / RAND_MAX; return fMin + f * (fMax - fMin); }
Recuerde llamar a srand () con una semilla adecuada cada vez que se inicie su programa.
[Editar] Esta respuesta es obsoleta ya que C ++ obtuvo su biblioteca aleatoria nativa no basada en C (vea la respuesta de Alessandro Jacopson) Pero, esto todavía se aplica a C
fuente
double f = rand() / (RAND_MAX + 1.0);
p(xxxxx,yyyyy)==0.0
Esta solución requiere C ++ 11 (o TR1).
#include <random> int main() { double lower_bound = 0; double upper_bound = 10000; std::uniform_real_distribution<double> unif(lower_bound,upper_bound); std::default_random_engine re; double a_random_double = unif(re); return 0; }
Para obtener más detalles, consulte "Generación de números aleatorios usando C ++ TR1" de John D. Cook .
Ver también Stroustrup's "Generación de números aleatorios" .
fuente
Debe ser eficiente, seguro para subprocesos y lo suficientemente flexible para muchos usos:
#include <random> #include <iostream> template<typename Numeric, typename Generator = std::mt19937> Numeric random(Numeric from, Numeric to) { thread_local static Generator gen(std::random_device{}()); using dist_type = typename std::conditional < std::is_integral<Numeric>::value , std::uniform_int_distribution<Numeric> , std::uniform_real_distribution<Numeric> >::type; thread_local static dist_type dist; return dist(gen, typename dist_type::param_type{from, to}); } int main(int, char*[]) { for(auto i = 0U; i < 20; ++i) std::cout << random<double>(0.0, 0.3) << '\n'; }
fuente
Si la precisión es un problema aquí, puede crear números aleatorios con una graduación más fina aleatorizando los bits significativos. Supongamos que queremos tener un doble entre 0.0 y 1000.0.
En MSVC (12 / Win32) RAND_MAX es 32767, por ejemplo.
Si usa el
rand()/RAND_MAX
esquema común , sus brechas serán tan grandes como1.0 / 32767.0 * ( 1000.0 - 0.0) = 0.0305 ...
En el caso de IEE 754 variables dobles (53 bits significativos) y aleatorización de 53 bits, la brecha de aleatorización más pequeña posible para el problema de 0 a 1000 será
2^-53 * (1000.0 - 0.0) = 1.110e-13
y por lo tanto significativamente más bajo.
La desventaja es que se necesitarán 4 llamadas rand () para obtener el número entero aleatorio (asumiendo un RNG de 15 bits).
double random_range (double const range_min, double const range_max) { static unsigned long long const mant_mask53(9007199254740991); static double const i_to_d53(1.0/9007199254740992.0); unsigned long long const r( (unsigned long long(rand()) | (unsigned long long(rand()) << 15) | (unsigned long long(rand()) << 30) | (unsigned long long(rand()) << 45)) & mant_mask53 ); return range_min + i_to_d53*double(r)*(range_max-range_min); }
Si se desconoce el número de bits para la mantisa o el RNG, es necesario obtener los valores respectivos dentro de la función.
#include <limits> using namespace std; double random_range_p (double const range_min, double const range_max) { static unsigned long long const num_mant_bits(numeric_limits<double>::digits), ll_one(1), mant_limit(ll_one << num_mant_bits); static double const i_to_d(1.0/double(mant_limit)); static size_t num_rand_calls, rng_bits; if (num_rand_calls == 0 || rng_bits == 0) { size_t const rand_max(RAND_MAX), one(1); while (rand_max > (one << rng_bits)) { ++rng_bits; } num_rand_calls = size_t(ceil(double(num_mant_bits)/double(rng_bits))); } unsigned long long r(0); for (size_t i=0; i<num_rand_calls; ++i) { r |= (unsigned long long(rand()) << (i*rng_bits)); } r = r & (mant_limit-ll_one); return range_min + i_to_d*double(r)*(range_max-range_min); }
Nota: No sé si el número de bits para unsigned long long (64 bits) es mayor que el número de bits de doble mantisa (53 bits para IEE 754) en todas las plataformas o no. Probablemente sería "inteligente" incluir un cheque como
if (sizeof(unsigned long long)*8 > num_mant_bits) ...
si este no fuera el caso.fuente
Este fragmento es directamente de The C ++ Programming Language (cuarta edición) de Stroustrup, §40.7; requiere C ++ 11:
#include <functional> #include <random> class Rand_double { public: Rand_double(double low, double high) :r(std::bind(std::uniform_real_distribution<>(low,high),std::default_random_engine())){} double operator()(){ return r(); } private: std::function<double()> r; }; #include <iostream> int main() { // create the random number generator: Rand_double rd{0,0.5}; // print 10 random number between 0 and 0.5 for (int i=0;i<10;++i){ std::cout << rd() << ' '; } return 0; }
fuente
algo como esto:
#include <iostream> #include <time.h> using namespace std; int main() { const long max_rand = 1000000L; double x1 = 12.33, x2 = 34.123, x; srandom(time(NULL)); x = x1 + ( x2 - x1) * (random() % max_rand) / max_rand; cout << x1 << " <= " << x << " <= " << x2 << endl; return 0; }
fuente