summaryrefslogtreecommitdiff
path: root/indra/llcommon/llrand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llrand.cpp')
-rw-r--r--indra/llcommon/llrand.cpp104
1 files changed, 39 insertions, 65 deletions
diff --git a/indra/llcommon/llrand.cpp b/indra/llcommon/llrand.cpp
index cb28a8f5c3..33afc50cf7 100644
--- a/indra/llcommon/llrand.cpp
+++ b/indra/llcommon/llrand.cpp
@@ -58,46 +58,14 @@
* to restore uniform distribution.
*/
-// *NOTE: The system rand implementation is probably not correct.
-#define LL_USE_SYSTEM_RAND 0
+static LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed());
-#if LL_USE_SYSTEM_RAND
-#include <cstdlib>
-#endif
+// no default implementation, only specific F64 and F32 specializations
+template <typename REAL>
+inline REAL ll_internal_random();
-#if LL_USE_SYSTEM_RAND
-class LLSeedRand
-{
-public:
- LLSeedRand()
- {
-#if LL_WINDOWS
- srand(LLUUID::getRandomSeed());
-#else
- srand48(LLUUID::getRandomSeed());
-#endif
- }
-};
-static LLSeedRand sRandomSeeder;
-inline F64 ll_internal_random_double()
-{
-#if LL_WINDOWS
- return (F64)rand() / (F64)RAND_MAX;
-#else
- return drand48();
-#endif
-}
-inline F32 ll_internal_random_float()
-{
-#if LL_WINDOWS
- return (F32)rand() / (F32)RAND_MAX;
-#else
- return (F32)drand48();
-#endif
-}
-#else
-static LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed());
-inline F64 ll_internal_random_double()
+template <>
+inline F64 ll_internal_random<F64>()
{
// *HACK: Through experimentation, we have found that dual core
// CPUs (or at least multi-threaded processes) seem to
@@ -108,15 +76,35 @@ inline F64 ll_internal_random_double()
return rv;
}
+template <>
+inline F32 ll_internal_random<F32>()
+{
+ return F32(ll_internal_random<F64>());
+}
+
+/*------------------------------ F64 aliases -------------------------------*/
+inline F64 ll_internal_random_double()
+{
+ return ll_internal_random<F64>();
+}
+
+F64 ll_drand()
+{
+ return ll_internal_random_double();
+}
+
+/*------------------------------ F32 aliases -------------------------------*/
inline F32 ll_internal_random_float()
{
- // The clamping rules are described above.
- F32 rv = (F32)gRandomGenerator();
- if(!((rv >= 0.0f) && (rv < 1.0f))) return fmod(rv, 1.f);
- return rv;
+ return ll_internal_random<F32>();
+}
+
+F32 ll_frand()
+{
+ return ll_internal_random_float();
}
-#endif
+/*-------------------------- clamped random range --------------------------*/
S32 ll_rand()
{
return ll_rand(RAND_MAX);
@@ -130,42 +118,28 @@ S32 ll_rand(S32 val)
return rv;
}
-F32 ll_frand()
-{
- return ll_internal_random_float();
-}
-
-F32 ll_frand(F32 val)
+template <typename REAL>
+REAL ll_grand(REAL val)
{
// The clamping rules are described above.
- F32 rv = ll_internal_random_float() * val;
+ REAL rv = ll_internal_random<REAL>() * val;
if(val > 0)
{
- if(rv >= val) return 0.0f;
+ if(rv >= val) return REAL();
}
else
{
- if(rv <= val) return 0.0f;
+ if(rv <= val) return REAL();
}
return rv;
}
-F64 ll_drand()
+F32 ll_frand(F32 val)
{
- return ll_internal_random_double();
+ return ll_grand<F32>(val);
}
F64 ll_drand(F64 val)
{
- // The clamping rules are described above.
- F64 rv = ll_internal_random_double() * val;
- if(val > 0)
- {
- if(rv >= val) return 0.0;
- }
- else
- {
- if(rv <= val) return 0.0;
- }
- return rv;
+ return ll_grand<F64>(val);
}