Ir al contenido principal

C: Generando números aleatorios (random)...

Generar números aleatorios es algo que se requiere en muchos programas y con diversos objetivos. Al simular el lanzamiento de un dado, una moneda, repartir cartas o simplemente mostrar números al azar dentro de un intervalo, requerimos de ellos. A continuación veremos cómo lograr generar estos números random en C.

Aclaración inicial: Los números que obtendremos en realidad son pseudoaleatorios, ya que no son netamente aleatorios sino el resultado de ciertos cálculos especificados en el algoritmo de las funciones que usaremos. Pero esta simulación de números random que obtendremos nos servirá de igual manera a fines prácticos.

La función rand( ):

Esta función se encuentra en la librería stdlib.h y lo que hace es devolvernos un número entero aleatorio en un rango que va desde 0 hasta una constante llamada RAND_MAX que está definido como 0x7FFF (si lo quisiéramos mostrar en C como un int sería al menos 32767, en caso de mostrarlo como un long long tendría cerca de 17 cifras... en resumen es un número grande).

Pero normalmente nosotros queremos que el número que nos genere la función se encuentre dentro de un determinado rango y que seguramente será mucho menor. Veamos algunas formas de obtener este resultado.

Números aleatorios entre 0 y n:

Si queremos obtener un random entre 0 y n, podríamos hacerlo de la siguiente manera:


Donde si n fuera 10 tendríamos lo siguiente:


Como vemos en la misma imagen, se hace de la misma manera para cualquier número entre 0 y n. 

Números aleatorios entre m y n:

En otras ocasiones, puede que queramos generar un random en un intervalo que no comience en 0. Para estos casos la regla general sería la siguiente, donde m sería el límite inferior del intervalo y n el superior.


En este caso si quisiéramos que el número generado estuviera, por ejemplo, entre 50 y 100, tendríamos algo así:


Todo muy lindo, pero si ejecutamos el programa varias veces veremos que siempre nos genera el mismo número aunque nos cansemos de ejecutarlo ... ¿y qué hacemos?... no se preocupen que ahora mostraremos la forma de solucionar eso.

Función srand( ):

Como vimos, rand llega siempre al mismo resultado si lo usamos tal como lo explicamos. Esto sucede porque la función lo que hace es realizar cálculos comenzando en lo que llamamos semilla (un número inicial), por lo que al llegar al mismo punto tendremos el mismo resultado si no se modifica esta semilla. 

Para modificarla tenemos la función srand, a la que le pasaremos como argumento un número que se convertirá en la famosa semilla que nos sacará de líos.

Pero... si colocamos un número fijo (o incluso uno generado con rand) como semilla estaremos en la misma que al comienzo ya que siempre empezará desde el mismo punto y los cálculos devolverán el mismo resultado. 

Si quieren comprobarlo por ustedes mismos, pueden probar lo que acabo de decir con algo así:


Usando el número fijo 1 como semilla obtendremos siempre el mismo resultado. Si colocaríamos esto dentro de un bucle for e imprimiéramos en pantalla el resultado veríamos esto:



Todas las veces nos genera el mismo número tal y como lo anticipamos. Pero no todo está perdido, lo que haremos para lograr que genere distintos números aleatorios cada vez será pasarle a srand la hora como argumento, y como la hora del sistema está en constante cambio ¡la semilla irá cambiando! y lograremos lo que buscamos.

Para hacer esto, debemos incluir la librería time.h y usaremos su función time( ) como argumento de srand.

Con lo que en nuestro ejemplo tendríamos:


Y si ejecutamos varias veces el programa veremos que ahora sí van cambiando los números generados.

Generando números aleatorios con decimales:

En caso que quisiéramos generar números random con decimales, deberíamos usar las funciones drand48 y srand48 cuyos usos son similares que rand y srand. Estas funciones sólo funcionan en Linux, no es posible utilizarlas en Windows.

Veamos cómo las usaríamos para generar números aleatorios con decimales entre m y n:



Librería conio.h: random( ) y randomize( ):

Si estamos programando en un IDE como Borland C, podemos utilizar la librería conio.h que no es estándar pero que tiene otras funciones para generar estos números aleatorios: random y randomize.

Random funciona de manera similar a rand, donde si queremos generar un número aleatorio entre 0 y 99 tendríamos algo así:


Generalizando: si queremos generar un número entre 0 y n:


Y si queremos generar un número entre m y n tendríamos:


Siguiendo la generalización anterior, si quisiéramos un número entre 10 y 99 deberíamos hacer:



Si colocamos el código de esta manera, tendremos el mismo problema que con rand al comienzo: generará siempre el mismo número. Para evitar eso, usaremos la función randomize, cuyo uso es tan sencillo como agregar lo siguiente al inicio de la función main o antes de usar random:




Comentarios

  1. como genero aleatorimente solo los numeros 2,3,5 sin que salga el 4 no me sale .....

    ResponderEliminar
  2. Hola! muy bueno, me gustaría que me ayudaras en algo...
    y es que es lo siguiente: Quiero hacer un juego del ahorcado (proyecto) y la parte que me es difícil es esta; En dos archivos de texto se deben tener 12 palabras y la descripción de cada una de ellas, las cuales servirán para el desarrollo del juego. Se deberá generar un número aleatorio del 1 al 12 para así mostrar en pantalla con el símbolo de piso ( _ ), la cantidad de caracteres que tiene la palabra a adivinar.

    Ya la lectura de los archivos lo tengo listo pero la funcion de los numero aleatorios, no sé en que parte ubicarlos en estos mismos, me ayudarías?

    ResponderEliminar
  3. Muy buenas disculpen necesito ayuda con algo.
    Necesito crear 3 números aleatorios distintos y poder manipular a cada numero luego, o sea que los 3 números que se generen de formas random me queden como una variable independiente, ¿como puedo hacerlo ?

    ResponderEliminar
  4. usando srand(time(NULL)) y rand() & m me sale el mismo número LOLLLLLL

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

C: Conversiones de tipo (casting) en C...

El casting o simplemente cast  nos permite hacer una conversión explícita de un tipo de dato a otro, a criterio del programador siempre y cuando estos tipos sean compatibles. Este cast se realiza a través de un operador de conversión de tipos (type casting operator) y es un recurso a tener en cuenta ya que hay situaciones en que nos puede resultar de gran utilidad. Hacer uso de un cast es tan sencillo como poner (tipo de dato)  delante de la expresión o variable a convertir. Veamos un ejemplo: Declaramos una variable de tipo int con un identificador tan creativo como "a" y le realizamos diferentes cast a a para mostrarlo como si fuera un float, un double y un char en un printf. Lo que obtendríamos en pantalla sería lo siguiente: Donde tenemos el valor de nuestro a, a convertido en float y double (mostrándolo con 3 cifras decimales) y a convertido en char. Si vemos este último caso, al hacer la conversión de "a" a char toma a como el código ascii de

C: Ejemplos: Congruencia de Zeller (nivel básico) ...

La Congruencia de Zeller es un algoritmo que se atribuye al matemático alemán Julius Christian Johannes Zeller que vivió en el siglo XIX. Este algoritmo nos permite determinar el día de la semana que le corresponde a una fecha determinada del calendario Gregoriano. La fórmula que nosotros usaremos (con algunas modificaciones respecto de la original para poder usarla en  informática) es la siguiente: Donde h es el día de la semana (entre 0 y 6), J es año/100 (la centuria) y K es año mod 100 (el año de la centuria). Y hay que tener en cuenta que los meses de enero y febrero cuentan como el mes 13 y 14 del año anterior. Ahora que tenemos la fórmula, programemos el algoritmo en C mediante el uso de una función: Analicemos el código paso a paso: Tenemos en cuenta el caso de enero y febrero: Dijimos que estos meses corresponden a los meses 13 y 14 del año anterior por lo que los asignamos como corresponde (mes + 12 , que dará 13 para enero y 14 para febrero) y le rest

Algoritmos: Resolución de problemas y refinamientos en pseudocódigo...

En otras entradas, vimos las partes que debe tener nuestro algoritmo en pseudocódigo y las estructuras que utilizaremos para resolverlo. Ahora llega el turno de implementar todo en conjunto para dar origen a nuestra creación. Pero ¿cómo resolvemos un problema así? Para hacerlo, utilizaremos lo que llamamos refinamientos sucesivos. Este concepto consiste en dividir el problema en subproblemas más pequeños y a estos, a su vez, en otros más pequeños; y así sucesivamente hasta que la solución de los últimos sea trivial, sencillo de resolver. Luego usaremos todas las soluciones obtenidas para armar la solución de nuestro problema mayor. Este principio, tiene base en parte de la técnica divide and conquer (dependiendo de la traducción: "divide y vencerás") que es una de las muchas técnicas de resolución de algoritmos existentes. Como vemos, al dividir el problema en otros más pequeños y más fáciles de resolver, podemos pasar de un problema complicado a uno cuya solución es much