¿Cómo obtengo un rango específico de números de rand ()?

srand(time(null)); printf("%d", rand()); 

Da un número aleatorio de alto rango (0-32000ish), pero solo necesito alrededor de 0-63 o 0-127, aunque no estoy seguro de cómo hacerlo. ¿Alguna ayuda?

 rand() % (max_number + 1 - minimum_number) + minimum_number 

Entonces, para 0-65:

 rand() % (65 + 1 - 0) + 0 

(obviamente, puedes dejar el 0 apagado, pero está ahí para completarlo).

Tenga en cuenta que esto sesgará un poco la aleatoriedad, pero probablemente no le preocupe nada si no está haciendo algo especialmente delicado.

Chequea aquí

http://c-faq.com/lib/randrange.html

Para cualquiera de estas técnicas, es sencillo cambiar el rango, si es necesario; números en el rango [M, N] podrían generarse con algo como

 M + rand() / (RAND_MAX / (N - M + 1) + 1) 

Tomar el módulo del resultado, como han afirmado los otros carteles, le dará algo que es casi aleatorio, pero no perfectamente.

Considere este ejemplo extremo, suponga que quiere simular un lanzamiento de moneda, regresando 0 o 1. Puede hacer esto:

 isHeads = ( rand() % 2 ) == 1; 

Parece bastante inofensivo, ¿verdad? Supongamos que RAND_MAX es solo 3. Es mucho más alto, por supuesto, pero el punto aquí es que hay un sesgo cuando se usa un módulo que no divide RAND_MAX de manera uniforme. Si quieres números aleatorios de alta calidad, vas a tener un problema.

Considera mi ejemplo. Los posibles resultados son:

 rand() freq. rand() % 2 0 1/3 0 1 1/3 1 2 1/3 0 

Por lo tanto, “colas” ocurrirá el doble de frecuencia que “cabezas”!

El Sr. Atwood discute este asunto en este artículo de Coding Horror

Como otros han notado, simplemente el uso de un módulo sesgará las probabilidades de los números individuales de modo que se prefieran números más pequeños.

Una solución muy ingeniosa y buena para ese problema se usa en la clase java.util.Random de Java:

 public int nextInt(int n) { if (n <= 0) throw new IllegalArgumentException("n must be positive"); if ((n & -n) == n) // ie, n is a power of 2 return (int)((n * (long)next(31)) >> 31); int bits, val; do { bits = next(31); val = bits % n; } while (bits - val + (n-1) < 0); return val; } 

Me tomó un tiempo entender por qué funciona y lo dejo como un ejercicio para el lector, pero es una solución bastante concisa que asegurará que los números tengan las mismas probabilidades.

La parte importante en ese fragmento de código es la condición para el ciclo while, que rechaza los números que caen en el rango de números que de lo contrario daría lugar a una distribución desigual.

Puedes usar esto:

 int random(int min, int max){ return min + rand() / (RAND_MAX / (max - min + 1) + 1); } 

Desde el:

Lista de preguntas frecuentes comp.lang.c · Pregunta 13.16

P: ¿Cómo puedo obtener enteros aleatorios en un cierto rango?

A: La forma obvia,

 rand() % N /* POOR */ 

(que intenta devolver números de 0 a N-1) es pobre, porque los bits de bajo orden de muchos generadores de números aleatorios son angustiosamente no aleatorios. (Consulte la pregunta 13.18.) Un método mejor es algo así como

 (int)((double)rand() / ((double)RAND_MAX + 1) * N) 

Si prefiere no usar punto flotante, otro método es

 rand() / (RAND_MAX / N + 1) 

Si solo necesitas hacer algo con probabilidad 1 / N, podrías usar

 if(rand() < (RAND_MAX+1u) / N) 

Todos estos métodos obviamente requieren conocer RAND_MAX (que ANSI # define), y suponer que N es mucho menor que RAND_MAX. Cuando N está cerca de RAND_MAX, y si el rango del generador de números aleatorios no es un múltiplo de N (es decir, si (RAND_MAX + 1)% N! = 0), todos estos métodos se rompen: algunos resultados ocurren con más frecuencia que otros. (El uso de coma flotante no ayuda; el problema es que rand devuelve RAND_MAX + 1 valores distintos, que no siempre se pueden dividir uniformemente en N cubos). Si esto es un problema, lo único que se puede hacer es llamar al rand múltiple veces, descartando ciertos valores:

 unsigned int x = (RAND_MAX + 1u) / N; unsigned int y = x * N; unsigned int r; do { r = rand(); } while(r >= y); return r / x; 

Para cualquiera de estas técnicas, es sencillo cambiar el rango, si es necesario; números en el rango [M, N] podrían generarse con algo como

 M + rand() / (RAND_MAX / (N - M + 1) + 1) 

(Tenga en cuenta, por cierto, que RAND_MAX es una constante que le dice cuál es el rango fijo de la función rand de la biblioteca C. No puede establecer RAND_MAX a algún otro valor, y no hay forma de solicitar ese rand devolver números en algún otro rango .)

Si está comenzando con un generador de números aleatorios que devuelve valores de punto flotante entre 0 y 1 (como la última versión de PMrand aludida en la pregunta 13.15 , o drand48 en la pregunta 13.21 ), todo lo que tiene que hacer para obtener enteros de 0 a N-1 multiplica la salida de ese generador por N:

 (int)(drand48() * N) 

Enlaces adicionales

Referencias: K & R2 Sec. 7.8.7 p. 168 PCS Sec. 11 p. 172

Cita de: http://c-faq.com/lib/randrange.html

 double scale = 1.0 / ((double) RAND_MAX + 1.0); int min, max; ... rval = (int)(rand() * scale * (max - min + 1) + min); 

Si no te preocupa excesivamente la ‘aleatoriedad’ de los bits de orden inferior, simplemente haz rand ()% HI_VAL.

También:

 (double)rand() / (double)RAND_MAX; // lazy way to get [0.0, 1.0) 

La forma ingenua de hacerlo es:

 int myRand = rand() % 66; // for 0-65 

Es probable que sea una distribución muy poco uniforme (dependiendo de su valor máximo), pero es bastante cercana.

Para explicar por qué no es bastante uniforme, considere este ejemplo muy simplificado:
Supongamos que RAND_MAX es 4 y quiere un número de 0-2. Los valores posibles que puede obtener se muestran en esta tabla:

 rand() | rand() % 3 ---------+------------ 0 | 0 1 | 1 2 | 2 3 | 0 

Ver el problema? Si su valor máximo no es un divisor par de RAND_MAX, será más probable que elija valores pequeños. Sin embargo, dado que RAND_MAX generalmente es 32767, es probable que el sesgo sea lo suficientemente pequeño como para salirse con la suya para la mayoría de los propósitos.

Hay varias formas de evitar este problema; mira aquí para una explicación de cómo maneja Random de Java.

Actualizado para no usar un #define

 double RAND(double min, double max) { return (double)rand()/(double)RAND_MAX * (max - min) + min; } 

rand () devolverá números entre 0 y RAND_MAX, que es al menos 32767.

Si desea obtener un número dentro de un rango, puede usar módulo.

 int value = rand() % 66; // 0-65 

Para mayor precisión, consulte este artículo . Discute por qué el módulo no es necesariamente bueno (malas distribuciones, especialmente en el extremo superior), y ofrece varias opciones.

Creo que lo siguiente lo hace a la derecha. Ha pasado un tiempo desde que toqué C. La idea es usar la división ya que el módulo no siempre da resultados aleatorios. Agregué 1 a RAND_MAX ya que hay muchos valores posibles que provienen de rand, incluyendo 0. Y como el rango también es 0 inclusive, agregué 1 también. Creo que las matemáticas están arregladas correctamente para evitar problemas matemáticos enteros.

 #define MK_DIVISOR(max) ((int)((unsigned int)RAND_MAX+1/(max+1))) num = rand()/MK_DIVISOR(65); 

si te importa la calidad de tus números aleatorios, no uses rand ()

use algún otro prng como http://en.wikipedia.org/wiki/Mersenne_twister o uno de los otros prng de alta calidad disponibles

entonces solo ve con el módulo.

Solo para agregar algunos detalles adicionales a las respuestas existentes.

La operación mod % siempre realizará una división completa y, por lo tanto, producirá un rest menor que el divisor.

x% y = x – (y * piso ((x / y)))

Un ejemplo de una función de búsqueda de rango aleatorio con comentarios:

 uint32_t rand_range(uint32_t n, uint32_t m) { // size of range, inclusive const uint32_t length_of_range = m - n + 1; // add n so that we don't return a number below our range return (uint32_t)(rand() % length_of_range + n); } 

Otra propiedad interesante según lo anterior:

x% y = x, si x

 const uint32_t value = rand_range(1, RAND_MAX); // results in rand() % RAND_MAX + 1 // TRUE for all x = RAND_MAX, where x is the result of rand() assert(value == RAND_MAX); result of rand() 
 2 cents (ok 4 cents): n = rand() x = result l = limit n/RAND_MAX = x/l Refactor: (l/1)*(n/RAND_MAX) = (x/l)*(l/1) Gives: x = l*n/RAND_MAX int randn(int limit) { return limit*rand()/RAND_MAX; } int i; for (i = 0; i < 100; i++) { printf("%d ", randn(10)); if (!(i % 16)) printf("\n"); } > test 0 5 1 8 5 4 3 8 8 7 1 8 7 5 3 0 0 3 1 1 9 4 1 0 0 3 5 5 6 6 1 6 4 3 0 6 7 8 5 3 8 7 9 9 5 1 4 2 8 2 7 8 9 9 6 3 2 2 8 0 3 0 6 0 0 9 2 2 5 6 8 7 4 2 7 4 4 9 7 1 5 3 7 6 5 3 1 2 4 8 5 9 7 3 1 6 4 0 6 5 

El solo uso de rand () le dará los mismos números aleatorios cuando ejecute el progtwig varias veces. es decir, cuando ejecuta su progtwig por primera vez produciría el número aleatorio x, y y z. Si ejecuta el progtwig nuevamente, producirá los mismos números x, yy z que observé.

La solución que encontré para mantenerla única cada vez es usar srand ()

Aquí está el código adicional,

 #include #include time_t t; srand((unsigned) time(&t)); int rand_number = rand() % (65 + 1 - 0) + 0 //ie Random numbers in range 0-65. 

Para establecer el rango, puede usar la fórmula: rand ()% (max_number + 1 – minimum_number) + minimum_number

¡Espero eso ayude!

O puedes usar esto:

 rand() / RAND_MAX * 65 

Pero no estoy seguro si es la más aleatoria o la más rápida de todas las respuestas aquí.