2010-07-21 30 views
6

Este códigosrand función en C++

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main() 
{ 
    printf ("First number: %d\n", rand() % 100); 
    srand (time(NULL)); 
    printf ("Random number: %d\n", rand() % 100); 
    srand (1); 
    printf ("Again the first number: %d\n", rand() %100); 

    return 0; 
} 

tiene el siguiente resultado:

First number: 41 
Random number: 13 
Again the first number: 41 

También existe la siguiente regla:

dos inicializaciones diferentes con la misma semilla, la instrucción el generador pseudoaleatorio para generar la misma sucesión de resultados para las llamadas subsiguientes a rand en ambos casos.

Entiendo las palabras, pero simplemente no entiendo el método en sí. ¿Por qué volvió 41 otra vez? ¿Es aleatorio o debe devolver el mismo resultado en todos los casos de acuerdo con este código?

+2

Esto hace que la depuración sea más fácil. Si se está ejecutando normalmente, use srant (time (NULL)). Si hay un error en su programa, no llame a srand() o llame a srand (1) y obtendrá la misma secuencia de números de las llamadas a rand(). Tenga en cuenta que cada llamada a rand generará el siguiente número en la secuencia, pero la secuencia siempre será la misma. Nota 2: solo debe llamar a srand() una vez en la aplicación. –

+0

@Martin York: Buen punto. Nunca pensé en esto desde el punto de vista de la depuración. Tiene sentido. – Lazer

Respuesta

7

Si llama rand() sin antes llamar srand(), el comportamiento es como si se llama a srand() con 1 como argumento.

Este comportamiento se define en el estándar C original. No tengo una copia completa de la misma mano, pero los estándares POSIX del Grupo abierto son la segunda mejor opción, ya que incorporan el estándar completo C (con algunas extensiones):

http://www.opengroup.org/onlinepubs/000095399/functions/rand.html

El srand() la función usa el argumento como una semilla para que una nueva secuencia de números pseudoaleatorios sea devuelta por llamadas subsecuentes a rand(). Si se llama a srand() con el mismo valor inicial, se repetirá la secuencia de números pseudoaleatorios. Si rand() se llama antes de cualquier llamada a srand() están hechos, la misma secuencia se genera como cuando srand() se llama en primer lugar con un valor de semilla 1.

El resultado real de una llamada rand() para cualquier semilla determinada es definida por la implementación, excepto que para cualquier semilla x, llame a n a rand() después de que la siembra del generador debe devolver el mismo resultado. Por lo tanto, durante su implementación siempre obtendrá 41 en la primera llamada rand() después de llamar al srand(1), y siempre obtendrá el mismo resultado (lo que sea) para la segunda llamada rand(), otras implementaciones pueden usar un algoritmo diferente que produzca resultados diferentes.

0

creo que éste puede ser un problema:

Si la semilla se establece en 1, el generador se reinicializa a su valor inicial y produce los mismos valores que antes de cualquier llamada a rand o srand.

srand reference

0

Llamar a srand con un valor de 1 restablece el generador a su estado inicial cuando se inició el programa.

7

El estándar C++ difiere al estándar C para rand y srand (ver sección 26.8 de C++ 0x):

La función rand tiene la semántica especificados en la norma C, excepto que la aplicación puede especificar que las funciones de la biblioteca particulares pueden llamar rand.

El estándar C (7.20.2.2 de C99) afirma categóricamente:

Si rand se llama antes se han realizado llamadas a srand, la misma secuencia se genera como cuando srand es primero llama con un valor de semilla de 1.

Así que la primera vez que llame rand, la semilla es 1. también es 1 la tercera vez que la llame por lo que se obtiene el mismo valor.

La segunda vez que llamó a rand, la semilla se configuró en función de la hora actual, por lo que obtuvo un resultado diferente. Por lo general, no es una buena idea volver a inicializar el generador de números aleatorios a menos que realmente desee en la misma secuencia (como en las pruebas).

0

srand(3) le permite obtener una salida repetible desde el generador de números aleatorios. De esta forma, puede escribir programas que dependen de números aleatorios, pero probarlos de manera determinista. (Normalmente, al tener una opción de línea de comandos para llamar al srand() con un argumento proporcionado, para que pueda ejecutarse cien veces con 1, 2, 3, 4, 5, ... como entradas)

Así que esto es comportarse como se esperaba

0

Probablemente sea porque en su llamada inicial a rand, el generador de números aleatorios no se ha sembrado, por lo que usa un valor predeterminado de 1 para inicializarlo.