domingo, 18 de enero de 2009

Manual de PHP 15. Operaciones: Números Aleatorios

PHP dispone de dos funciones capaces de generar números aleatorios. Se trata de la función rand() y de la función mejorada mt_rand().

El valor mínimo del intervalo que contiene los números aleatorios que pueden ser generados es CERO en ambos casos y los valores máximos de cada opción pueden determinarse mediante las funciones getrandmax(), para el primer generador, y mt_getrandmax(), para el segundo.

Veamos cuales son esos valores en cada uno de los casos.

Valores máximos de los generadores de números aleatorios
Generador rand() Generador mt_rand()
SintaxisValor máximo SintaxisValor máximo
echo getrandmax() 32767 echo mt_getrandmax() 2147483647

Según las librerías que esté usando PHP, puede ocurrir que los valores máximos con ambos generadores sean iguales. No es ese nuestro caso, como puedes comprobar.


La forma más simple

La forma más simple -y más desaconsejable- de generación de un número aleatorio es esta:

Generación de un número aleatorio
Generador rand() Generador mt_rand()
SintaxisNº aleatorio SintaxisNº aleatorio
echo rand() 6843 echo mt_rand() 1854348533


Una semilla que mejora la aleatoriedad

Si antes de escribir la función rand() en un caso, o mt_rand() en el otro escribimos:

srand((double)microtime()*1000000), en el primer caso y/o

mt_srand((double)microtime()*1000000), en el segundo

estaremos introduciendo una semilla (al margen comentamos la forma en que se genera) que mejora sustancialmente la aleatoriedad del los números obtenidos.

Aquí tenemos un ejemplo:

Generación de un número aleatorio con semilla
Generador rand()
SintaxisNº aleatorio
srand((double)microtime()*1000000);
echo rand()
18260
Generador mt_rand()
SintaxisNº aleatorio
mt_srand((double)microtime()*1000000);
echo mt_rand()
2126112235

Manteniendo la sintaxis anterior -no te olvides de las semillitas famosas- se pueden generar números aleatorios comprendidos dentro del intervalo que preestablezcamos.

Bastaría con añadir los valores de los extremos de ese intervalo como parámetros de la función. La sintaxis sería esta:
rand(extremo inferior , extremo superior)
y para la función mejorada
mt_rand(extremo inferior , extremo superior)


Generación de un número aleatorio delimitando intervalos
Generador rand()
SintaxisNº aleatorio
srand((double)microtime()*1000000);
echo rand(1,300)
58
Generador mt_rand()
SintaxisNº aleatorio
mt_srand((double)microtime()*1000000);
echo mt_rand(1,300)
48

El origen de la semilla

El valor Unix Epoch

El conocido como tiempo UNIX –o también Unix Epoch- es un sistema referencia de tiempo cuya unidad son los segundos y que tiene su valor cero a las 0:00:00 horas (GMT) del día uno de enero de 1970.

La funcion time()

La función time() devuelve una cadena con el número de segundos transcurridos desde el comienzo de la Unix Epoch.

¿Que cuantos son? Pues mira, hasta este mismo instante han transcurrido:

1 232 267 405 segundos

desde el comienzo del tiempo UNIX.

La funcion microtime()

Usando la función microtime() se obtiene una cadena a la que, además del número de segundos transcurridos desde el comienzo de la Unix Epoch, se añade – al comienzo de ella y separado por un espacio– la parte decimal de ese tiempo expresada en microsegundos.

Este es el valor de la cadena devuelta por microtime() en este instante:

0.99230500 1232267405

donde, como verás, aparece la fracción decimal del tiempo Unix Epoch delante de su valor entero.

(double)microtime()

Dado que con microtime() obtenemos una cadena, es posible convertirla en número de coma flotante anteponiendo a esa función (double).

Una vez cambiado el tipo de variable el valor devuelto por microtime se convierte en:

0.992395

que como puedes observar es un número con seis decimales (si las últimas cifras son ceros no se visualizarán).

Si se multiplica el valor anterior por 1.000.000 obtenemos un número de seis cifras y valor entero que puede cambiar de valor cada millonésima de segundo.

5490

¡Fíjate que ha cambiado! La diferencia no es otra cosa que el tiempo transcurrido entre los instantes en que se ejecutaron ambas instrucciones.

Este número entero es utilizado por srand y mt_rand como semilla generadora de números aleatorios.






Fuente:
Página del ifstic: http://www.isftic.mepsyd.es/formacion/enred/

No hay comentarios: