[C con Clase] Numeros aleatorios
Steven Davidson
srd4121 en njit.edu
Mie Mar 25 17:59:17 CET 2009
Hola Vicente,
vicente lozano wrote:
> Hola,
>
> He escrito una clase error (adjuntas) para hacer unas simulaciones de
> filtrados.
>
> El problema es que los numeros aleatorios no me huelen muy bien
> porque por ejemplo, hago 300 "mediciones" con un error entre -20 y
> +20 unidades sobre una medida teorica de 10 y la media de las 300
> mediciones sale muy aproximada a 12 todo el tiempo. He probado a
> reseedear el random pero el resultado es el mismo todo el tiempo y no
> entiendo porque.
>
> A ver si me podeis echar una mano y depaso si veis algun fallo de
> disenyo sobre el codigo y eso pues agradeceria que me lo comentarais
> para aprender a hacer las cosas mejor.
>
Creo que tienes un error de diseño en la implementación de los
operadores aritméticos. Escribes lo siguiente:
double operator+( const double d, Error e );
double operator-( const double d, Error e );
double operator*( const double d, Error e );
double operator/( const double d, Error e );
ostream &operator<<( ostream &os, Error e );
El error común a estos prototipos, y equivalentes, es que pasas los
objetos de la clase 'Error' por copia. Esto implica que se instancia un
nuevo objeto local a cada función. Estas instanciaciones infieren que se
"reinicia", por así decirlo, el generador de números pseudo-aleatorios.
Esto es porque el constructor invoca 'srand()'. Deberías pasar los
objetos por referencia, pero como no tenemos intención de modificar el
objeto, lo tratamos como una constante; esto es,
double operator+( const double d, const Error &e );
double operator-( const double d, const Error &e );
...
De todas maneras, sugiero eliminar 'srand()' del constructor y
simplemente invocarla al principio de 'main()'. Si de verdad quieres
seguir una "filosofía" de la POO, entonces supongo que podrías crear una
variable estática para indicar si se ha iniciado o no el generador. Por
ejemplo,
class Error
{
static bool bIniciarGenerador;
...
};
bool Error::bIniciarGenerador = true;
Error::Error( double min, double max )
: _min(min), _max(max), _lastError(0)
{
if( bIniciarGenerador )
{
bIniciarGenerador = false;
srand( (unsigned) time(0) );
}
err();
}
Creo que hay otra manera, pero ahora mismo no caigo.
Espero que esto te solucione el problema de aleatoriedad.
Steven
Más información sobre la lista de distribución Cconclase