¿Cómo funciona módulo y rand ()?

Entonces, he estado loco con esto.

rand ()% 6 siempre producirá un resultado entre 0-5.

Sin embargo, cuando necesito entre, digamos 6-12.

Debería tener rand ()% 6 + 6

0+6 = 6. 1+6 = 7. ... 5+6 = 11. ??? 

Entonces, ¿necesito + 7 si quiero el intervalo 6-12? Pero entonces, 0 + 7 = 7. ¿Cuándo asignará aleatoriamente 6?

¿Que me estoy perdiendo aqui? ¿Cuál es la forma correcta de tener un número aleatorio entre 6 y 12? ¿Y por qué? Parece que me falta algo aquí.

Si C ++ 11 es una opción, entonces debe usar el encabezado aleatorio y uniform_int_distrubution . Como James señaló en los comentarios usando rand y % tiene muchos problemas, incluida una distribución sesgada:

 #include  #include  int main() { std::random_device rd; std::mt19937 e2(rd()); std::uniform_int_distribution dist(6, 12); for (int n = 0; n < 10; ++n) { std::cout << dist(e2) << ", " ; } std::cout << std::endl ; } 

si tiene que usar rand , esto debería hacer:

 rand() % 7 + 6 

Actualizar

Un mejor método para usar rand sería el siguiente:

 6 + rand() / (RAND_MAX / (12 - 6 + 1) + 1) 

Lo obtuve de las preguntas frecuentes de C y se explica cómo puedo obtener enteros aleatorios en un cierto rango? pregunta.

Actualización 2

Boost también es una opción:

 #include  #include  #include  int main() { boost::random::mt19937 gen; boost::random::uniform_int_distribution<> dist(6, 12); for (int n = 0; n < 10; ++n) { std::cout << dist(gen) << ", "; } std::cout << std::endl ; } 

Necesitas rand ()% 7 + 6.

Número más bajo de rand ()% 7: 0. Número más alto de rand ()% 7: 6.

0 + 6 = 6. 6 + 6 = 12.

La operación de módulo a % b calcula el rest de la división a / b . Obviamente, el rest de una división debe ser menor que b y si a es un entero positivo al azar, entonces a%b es un entero aleatorio en el rango 0 .. (b-1)


En los comentarios que mencionas:

rand ()% (max-min) + min

Este algoritmo produce valores en el rango medio abierto [min, max). (Es decir, max está fuera del rango, y simplemente denota el límite. Dado que estamos hablando de rangos de enteros, este rango es equivalente al rango cerrado [min, max-1]).

Cuando escribe ‘0 – 5’ o ‘6 – 12’ esos son rangos cerrados. Para usar la ecuación anterior, debe usar los valores que denotan el medio rango abierto equivalente: [0, 6) o [6, 13).

 rand() % (6-0) + 0 rand() % (13-6) + 6 

Tenga en cuenta que rand() % (max-min) + min es solo una generalización de la regla que aparentemente ya ha aprendido: que rand() % n produce valores en el rango 0 – (n-1). El rango medio abierto equivalente es [0, n), y rand() % n == rand() % (n-0) + 0 .

Entonces la lección es: no confunda los rangos semiabiertos para rangos cerrados.


Una segunda lección es que esto muestra otra forma en que es más fácil de usar que rand() y calcula manualmente sus propias distribuciones. El built-in uniform_int_distribution permite uniform_int_distribution directamente el rango deseado e inclusivo. Si quiere el rango 0 – 5, dice uniform_int_distibution<>(0, 5) , y si quiere el rango 6 – 12, entonces dice uniform_int_distribution<>(6, 12) .

 #include  #include  int main() { std::default_random_engine eng; std::uniform_int_distribution<> dist(6, 12); for (int i=0; i<10; ++i) std::cout << dist(eng) << " "; } 

rand()%7+6 es más escueto, pero eso no significa que sea más fácil de usar.

Hay un par de conceptos aquí.

Primero, está el rango: [ denota inclusivo. ) denota exclusivo.

El operador de módulo% n produce [0,n) – 0, .. n-1

Cuando agrega un valor a ese resultado, agrega el mismo valor a ambos extremos de los rangos:

%n + 6 = [n,n+6)

Ahora, si n es 6, como está en su caso, su salida será [0,6)

%6 + 6 = [6,12)

Ahora lo que quieres es [6,13)

Reste 6 de eso:

[0,7) + 6 => n%7 + 6

En segundo lugar, está la cuestión de usar rand (). Depende de si realmente le importa si sus datos son aleatorios o no. Si realmente te importa que sea aleatorio, te sugiero que veas la charla de Stefan T Lavalej sobre los peligros de usar rand () en Going Native 2013 este año. Él también entra en lo que deberías usar.

Si la aleatoriedad de rand () no le importa, entonces, por supuesto, úselo.