[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