llrand.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "llrand.h"
00035 #include "lluuid.h"
00036 
00066 // *NOTE: The system rand implementation is probably not correct.
00067 #define LL_USE_SYSTEM_RAND 0
00068 
00069 #if LL_USE_SYSTEM_RAND
00070 #include <cstdlib>
00071 #endif
00072 
00073 #if LL_USE_SYSTEM_RAND
00074 class LLSeedRand
00075 {
00076 public:
00077         LLSeedRand()
00078         {
00079 #if LL_WINDOWS
00080                 srand(LLUUID::getRandomSeed());
00081 #else
00082                 srand48(LLUUID::getRandomSeed());
00083 #endif
00084         }
00085 };
00086 static LLSeedRand sRandomSeeder;
00087 inline F64 ll_internal_random_double()
00088 {
00089 #if LL_WINDOWS
00090         return (F64)rand() / (F64)RAND_MAX; 
00091 #else
00092         return drand48();
00093 #endif
00094 }
00095 inline F32 ll_internal_random_float()
00096 {
00097 #if LL_WINDOWS
00098         return (F32)rand() / (F32)RAND_MAX; 
00099 #else
00100         return (F32)drand48();
00101 #endif
00102 }
00103 #else
00104 static LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed());
00105 inline F64 ll_internal_random_double()
00106 {
00107         // *HACK: Through experimentation, we have found that dual core
00108         // CPUs (or at least multi-threaded processes) seem to
00109         // occasionally give an obviously incorrect random number -- like
00110         // 5^15 or something. Sooooo, clamp it as described above.
00111         F64 rv = gRandomGenerator();
00112         if(!((rv >= 0.0) && (rv < 1.0))) return fmod(rv, 1.0);
00113         return rv;
00114 }
00115 
00116 inline F32 ll_internal_random_float()
00117 {
00118         // The clamping rules are described above.
00119         F32 rv = (F32)gRandomGenerator();
00120         if(!((rv >= 0.0f) && (rv < 1.0f))) return fmod(rv, 1.f);
00121         return rv;
00122 }
00123 #endif
00124 
00125 S32 ll_rand()
00126 {
00127         return ll_rand(RAND_MAX);
00128 }
00129 
00130 S32 ll_rand(S32 val)
00131 {
00132         // The clamping rules are described above.
00133         S32 rv = (S32)(ll_internal_random_double() * val);
00134         if(rv == val) return 0;
00135         return rv;
00136 }
00137 
00138 F32 ll_frand()
00139 {
00140         return ll_internal_random_float();
00141 }
00142 
00143 F32 ll_frand(F32 val)
00144 {
00145         // The clamping rules are described above.
00146         F32 rv = ll_internal_random_float() * val;
00147         if(val > 0)
00148         {
00149                 if(rv >= val) return 0.0f;
00150         }
00151         else
00152         {
00153                 if(rv <= val) return 0.0f;
00154         }
00155         return rv;
00156 }
00157 
00158 F64 ll_drand()
00159 {
00160         return ll_internal_random_double();
00161 }
00162 
00163 F64 ll_drand(F64 val)
00164 {
00165         // The clamping rules are described above.
00166         F64 rv = ll_internal_random_double() * val;
00167         if(val > 0)
00168         {
00169                 if(rv >= val) return 0.0;
00170         }
00171         else
00172         {
00173                 if(rv <= val) return 0.0;
00174         }
00175         return rv;
00176 }

Generated on Fri May 16 08:32:15 2008 for SecondLife by  doxygen 1.5.5