From 2295579eb790d6eff6e54e84c01da6de10809a71 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 22 May 2012 16:57:15 +0000 Subject: Better win_o ignores. The random number system is pretty much together. We need a few extra helper functions to cover some other good things, like normalized floating point numbers, etc. --- src/experimental/random.cpp | 24 ++++++++++++++++++ src/experimental/random.h | 51 +++++++++++++++++++++++++++++++++++++++ src/experimental/randombase.cpp | 8 ++++++ src/experimental/randombase.h | 17 +++++++++++++ src/experimental/randombasic.h | 8 +++--- src/experimental/randomcmwc.h | 8 +++--- src/experimental/randomsystem.cpp | 40 ++++++++++++++++++++++++++++++ src/experimental/randomsystem.h | 37 ++++++++++++++++++++++++++++ src/tests/random.cpp | 49 +++++++++++++++++++++++++++++++++++++ 9 files changed, 234 insertions(+), 8 deletions(-) create mode 100644 src/experimental/randomsystem.cpp create mode 100644 src/experimental/randomsystem.h create mode 100644 src/tests/random.cpp (limited to 'src') diff --git a/src/experimental/random.cpp b/src/experimental/random.cpp index c792772..725948a 100644 --- a/src/experimental/random.cpp +++ b/src/experimental/random.cpp @@ -4,5 +4,29 @@ * This file is part of the libbu++ library and is released under the * terms of the license contained in the file LICENSE. */ +#include "bu/random.h" +#include "bu/randombasic.h" + +Bu::Random::Random() : + pGen( NULL ) +{ + pGen = new RandomBasic(); +} + +Bu::Random::~Random() +{ + delete pGen; + pGen = NULL; +} + +int32_t Bu::Random::rand() +{ + return getInstance().pGen->rand(); +} + +void Bu::Random::seed( int32_t iSeed ) +{ + getInstance().pGen->seed( iSeed ); +} diff --git a/src/experimental/random.h b/src/experimental/random.h index c792772..ba26f21 100644 --- a/src/experimental/random.h +++ b/src/experimental/random.h @@ -4,5 +4,56 @@ * This file is part of the libbu++ library and is released under the * terms of the license contained in the file LICENSE. */ +#ifndef BU_RANDOM_H +#define BU_RANDOM_H +#include "bu/singleton.h" +#include + +namespace Bu +{ + class RandomBase; + class Random : public Bu::Singleton + { + friend class Bu::Singleton; + private: + Random(); + virtual ~Random(); + + public: + template + static void setGenerator() + { + delete getInstance().pGen; + getInstance().pGen = new cl(); + } + + template + static void setGenerator( t1 p1 ) + { + delete getInstance().pGen; + getInstance().pGen = new cl( p1 ); + } + + template + static void setGenerator( t1 p1, t2 p2 ) + { + delete getInstance().pGen; + getInstance().pGen = new cl( p1, p2 ); + } + + RandomBase &getGenerator() { return *pGen; } + + static int32_t rand(); + static void seed( int32_t iSeed ); + + private: + void checkInit(); + + private: + Bu::RandomBase *pGen; + }; +}; + +#endif diff --git a/src/experimental/randombase.cpp b/src/experimental/randombase.cpp index c792772..6514df3 100644 --- a/src/experimental/randombase.cpp +++ b/src/experimental/randombase.cpp @@ -4,5 +4,13 @@ * This file is part of the libbu++ library and is released under the * terms of the license contained in the file LICENSE. */ +#include "bu/randombase.h" +Bu::RandomBase::RandomBase() +{ +} + +Bu::RandomBase::~RandomBase() +{ +} diff --git a/src/experimental/randombase.h b/src/experimental/randombase.h index c792772..aff1d45 100644 --- a/src/experimental/randombase.h +++ b/src/experimental/randombase.h @@ -4,5 +4,22 @@ * This file is part of the libbu++ library and is released under the * terms of the license contained in the file LICENSE. */ +#ifndef BU_RANDOM_BASE_H +#define BU_RANDOM_BASE_H +#include +namespace Bu +{ + class RandomBase + { + public: + RandomBase(); + virtual ~RandomBase(); + + virtual void seed( int32_t iSeed )=0; + virtual int32_t rand()=0; + }; +}; + +#endif diff --git a/src/experimental/randombasic.h b/src/experimental/randombasic.h index 6eab9dc..a53e16f 100644 --- a/src/experimental/randombasic.h +++ b/src/experimental/randombasic.h @@ -7,19 +7,19 @@ #ifndef BU_RANDOM_BASIC_H #define BU_RANDOM_BASIC_H -#include +#include "bu/randombase.h" namespace Bu { - class RandomBasic + class RandomBasic : public RandomBase { public: RandomBasic(); virtual ~RandomBasic(); - void seed( int32_t iSeed ); + virtual void seed( int32_t iSeed ); - int32_t rand(); + virtual int32_t rand(); private: int64_t a, c, x; diff --git a/src/experimental/randomcmwc.h b/src/experimental/randomcmwc.h index 3a05383..747eb6a 100644 --- a/src/experimental/randomcmwc.h +++ b/src/experimental/randomcmwc.h @@ -7,19 +7,19 @@ #ifndef BU_RANDOM_CMWC_H #define BU_RANDOM_CMWC_H -#include +#include "bu/randombase.h" namespace Bu { - class RandomCmwc + class RandomCmwc : public RandomBase { public: RandomCmwc(); virtual ~RandomCmwc(); - void seed( int32_t iSeed ); + virtual void seed( int32_t iSeed ); - int32_t rand(); + virtual int32_t rand(); private: uint32_t *q, c; diff --git a/src/experimental/randomsystem.cpp b/src/experimental/randomsystem.cpp new file mode 100644 index 0000000..0501587 --- /dev/null +++ b/src/experimental/randomsystem.cpp @@ -0,0 +1,40 @@ +#include "bu/randomsystem.h" +#include "bu/file.h" + +Bu::RandomSystem::RandomSystem( Type eType ) : + eType( eType ), + pSrc( 0 ) +{ + switch( eType ) + { + case Bu::RandomSystem::Fast: + pSrc = new Bu::File("/dev/urandom", Bu::File::Read ); + break; + + case Bu::RandomSystem::Good: + pSrc = new Bu::File("/dev/random", Bu::File::Read ); + break; + } +} + +Bu::RandomSystem::~RandomSystem() +{ + delete pSrc; +} + +void Bu::RandomSystem::seed( int32_t /*iSeed*/ ) +{ + // Seed really has no effect here... + // on linux, if we were root, we could write data to random/urandom to + // perturb the data, but it's not necesarry +} + +int32_t Bu::RandomSystem::rand() +{ + if( !pSrc ) + throw Bu::ExceptionBase("Not initialized"); + int32_t i; + pSrc->read( &i, sizeof(int32_t) ); + return i; +} + diff --git a/src/experimental/randomsystem.h b/src/experimental/randomsystem.h new file mode 100644 index 0000000..7106d58 --- /dev/null +++ b/src/experimental/randomsystem.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2007-2012 Xagasoft, All rights reserved. + * + * This file is part of the libbu++ library and is released under the + * terms of the license contained in the file LICENSE. + */ +#ifndef BU_RANDOM_SYSTEM_H +#define BU_RANDOM_SYSTEM_H + +#include "bu/randombase.h" + +namespace Bu +{ + class File; + class RandomSystem : public RandomBase + { + public: + enum Type + { + Fast, + Good + }; + + RandomSystem( Type eType=Fast ); + virtual ~RandomSystem(); + + virtual void seed( int32_t iSeed ); + + virtual int32_t rand(); + + private: + Type eType; + File *pSrc; + }; +}; + +#endif diff --git a/src/tests/random.cpp b/src/tests/random.cpp new file mode 100644 index 0000000..3799803 --- /dev/null +++ b/src/tests/random.cpp @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include + +using namespace Bu; + +template +void coverage() +{ + T rand; + rand.seed( time( NULL ) ); + + uint32_t uBucket[78]; + memset( uBucket, 0, sizeof(uint32_t)*78 ); + + for( int j = 0; j < 1000000; j++ ) + { + uBucket[(int)(((uint32_t)rand.rand())/(double)(0xfffffffful)*78+0.5)]++; + } + + uint32_t uMax = 0; + for( int j = 0; j < 78; j++ ) + { + if( uMax < uBucket[j] ) + uMax = uBucket[j]; + } + + for( int y = 20; y >= 1; y-- ) + { + uint32_t iT = (uint32_t)((y/20.0)*uMax); + for( int x = 0; x < 78; x++ ) + { + sio << ((iT<=uBucket[x])?"#":" "); + } + sio << sio.nl; + } +} + +int main() +{ + coverage(); + coverage(); + coverage(); + + return 0; +} + -- cgit v1.2.3