Generar números aleatorios eficazmente con Rand()
Quizás te hayas podido dar cuenta que en C, utilizando la función rand() de la biblioteca estándar, se obtienen resultados decepcionantes, casi siempre los mismos.
Por ejemplo, si deseamos generar 5 números aleatorios uno después de otro:
#include <stdlib.h>
#include <stdio.h>
int main()
{
int i;
for(i=0; i<5; i++)
{
printf("%d\n", rand());
}
return 0;
}
Ejecutemos el programa y veamos el resultado:
41
18467
6334
26500
19169
Los resultados son significativamente diferentes, pero si volvemos a ejecutar el programa, tendremos la misma serie de números.
Para modificar el comportamiento del generador de números aleatorios, podemos modificar la variable sobre la que se basa para realizar los cálculos. A esto se le llama seed o semilla.
Esta semilla se modifica con la función srand():
srand(valor de la semilla)
Necesitamos un numero que no podamos predecir fácilmente y que varíe de un instante a otro. Por ejemplo, puedes tomar el número de ciclos utilizados por tu procesador desde el inicio. Puede ser obtenido, sobre procesadores x86 (intel, Amd etc...), con el comando ensamblador rdtsc. La escritura de una función rdtsc() llamando a este comando de ensamblador podrá facilitarte las cosas, la sintaxis siguiente funciona con gcc bajo Linux y la podrás encontrar con dev C++ bajo Windows.
#include <stdlib.h>
#include <stdio.h>
int rdtsc()
{
__asm__ __volatil__("rdtsc");
}
int main()
{
int i;
for(i=0; i<5; i++)
{
srand(rdtsc());
printf("%d\n", rand());
}
return 0;
}
Con este código, generaras números aleatorios más eficaces.
Nota: Esta solución funciona únicamente con los procesadores x86.
También evita activar optimizaciones en el compilador (option-O1,-O2-O3 etc ...), cuando utilices la función rdtsc.
PD: El
artículo original fue escrito por kilian, contribuidor de
CommentCaMarche