positive values, and add a unit test for rand<int>.legacy
@@ -31,26 +31,27 @@ EXTRA_DIST = easymesh/easymesh-scanner.l easymesh/easymesh-parser.y \ | |||
gpu/lolfx-scanner.l gpu/lolfx-parser.y | |||
liblolcore_headers = \ | |||
lol/base/base.h \ | |||
lol/base/all.h \ | |||
lol/base/log.h lol/base/array.h lol/base/types.h lol/base/array.h \ | |||
lol/base/assert.h lol/base/string.h lol/base/hash.h lol/base/map.h \ | |||
\ | |||
lol/math/math.h \ | |||
lol/math/all.h \ | |||
lol/math/functions.h lol/math/vector.h lol/math/half.h lol/math/real.h \ | |||
lol/math/remez.h lol/math/math.h lol/math/geometry.h lol/math/interp.h \ | |||
lol/math/rand.h \ | |||
\ | |||
lol/sys/sys.h \ | |||
lol/sys/all.h \ | |||
lol/sys/init.h lol/sys/file.h lol/sys/thread.h lol/sys/atomic.h \ | |||
lol/sys/timer.h \ | |||
\ | |||
lol/image/image.h \ | |||
lol/image/all.h \ | |||
lol/image/color.h \ | |||
\ | |||
lol/gpu/gpu.h \ | |||
lol/gpu/all.h \ | |||
lol/gpu/shader.h lol/gpu/indexbuffer.h lol/gpu/vertexbuffer.h \ | |||
lol/gpu/framebuffer.h lol/gpu/texture.h lol/gpu/lolfx.h \ | |||
\ | |||
lol/debug/debug.h \ | |||
lol/debug/all.h \ | |||
lol/debug/line.h \ | |||
\ | |||
lol/unit.h | |||
@@ -91,12 +91,12 @@ static inline int isnan(float f) | |||
#endif | |||
// Base types | |||
#include <lol/base/base.h> | |||
#include <lol/math/math.h> | |||
#include <lol/sys/sys.h> | |||
#include <lol/image/image.h> | |||
#include <lol/gpu/gpu.h> | |||
#include <lol/debug/debug.h> | |||
#include <lol/base/all.h> | |||
#include <lol/math/all.h> | |||
#include <lol/sys/all.h> | |||
#include <lol/image/all.h> | |||
#include <lol/gpu/all.h> | |||
#include <lol/debug/all.h> | |||
#include "numeric.h" | |||
@@ -8,8 +8,8 @@ | |||
// http://www.wtfpl.net/ for more details. | |||
// | |||
#if !defined __LOL_BASE_BASE_H__ | |||
#define __LOL_BASE_BASE_H__ | |||
#if !defined __LOL_BASE_ALL_H__ | |||
#define __LOL_BASE_ALL_H__ | |||
#include <lol/base/types.h> | |||
#include <lol/base/log.h> | |||
@@ -19,5 +19,5 @@ | |||
#include <lol/base/hash.h> | |||
#include <lol/base/map.h> | |||
#endif // __LOL_BASE_BASE_H__ | |||
#endif // __LOL_BASE_ALL_H__ | |||
@@ -8,10 +8,10 @@ | |||
// http://www.wtfpl.net/ for more details. | |||
// | |||
#if !defined __LOL_DEBUG_DEBUG_H__ | |||
#define __LOL_DEBUG_DEBUG_H__ | |||
#if !defined __LOL_DEBUG_ALL_H__ | |||
#define __LOL_DEBUG_ALL_H__ | |||
#include <lol/debug/lines.h> | |||
#endif // __LOL_DEBUG_DEBUG_H__ | |||
#endif // __LOL_DEBUG_ALL_H__ | |||
@@ -8,8 +8,8 @@ | |||
// http://www.wtfpl.net/ for more details. | |||
// | |||
#if !defined __LOL_GPU_GPU_H__ | |||
#define __LOL_GPU_GPU_H__ | |||
#if !defined __LOL_GPU_ALL_H__ | |||
#define __LOL_GPU_ALL_H__ | |||
#include <lol/gpu/shader.h> | |||
#include <lol/gpu/indexbuffer.h> | |||
@@ -18,5 +18,5 @@ | |||
#include <lol/gpu/framebuffer.h> | |||
#include <lol/gpu/lolfx.h> | |||
#endif // __LOL_GPU_GPU_H__ | |||
#endif // __LOL_GPU_ALL_H__ | |||
@@ -8,10 +8,10 @@ | |||
// http://www.wtfpl.net/ for more details. | |||
// | |||
#if !defined __LOL_IMAGE_IMAGE_H__ | |||
#define __LOL_IMAGE_IMAGE_H__ | |||
#if !defined __LOL_IMAGE_ALL_H__ | |||
#define __LOL_IMAGE_ALL_H__ | |||
#include <lol/image/color.h> | |||
#endif // __LOL_IMAGE_IMAGE_H__ | |||
#endif // __LOL_IMAGE_ALL_H__ | |||
@@ -8,8 +8,8 @@ | |||
// http://www.wtfpl.net/ for more details. | |||
// | |||
#if !defined __LOL_MATH_MATH_H__ | |||
#define __LOL_MATH_MATH_H__ | |||
#if !defined __LOL_MATH_ALL_H__ | |||
#define __LOL_MATH_ALL_H__ | |||
#include <lol/math/functions.h> | |||
#include <lol/math/half.h> | |||
@@ -17,6 +17,7 @@ | |||
#include <lol/math/vector.h> | |||
#include <lol/math/geometry.h> | |||
#include <lol/math/interp.h> | |||
#include <lol/math/rand.h> | |||
#endif // __LOL_MATH_MATH_H__ | |||
#endif // __LOL_MATH_ALL_H__ | |||
@@ -0,0 +1,114 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// | |||
// | |||
// The Random number generators | |||
// ---------------------------- | |||
// | |||
#if !defined __LOL_MATH_RAND_H__ | |||
#define __LOL_MATH_RAND_H__ | |||
#include <cstdlib> | |||
#include <stdint.h> | |||
namespace lol | |||
{ | |||
/* Random number generators */ | |||
template<typename T> static inline T rand(); | |||
template<typename T> static inline T rand(T a); | |||
template<typename T> static inline T rand(T a, T b); | |||
/* One-value random number generators */ | |||
template<typename T> static inline T rand(T a) | |||
{ | |||
return rand<T>() % a; | |||
} | |||
template<> | |||
inline half rand<half>(half a) { return a * std::rand() / RAND_MAX; } | |||
template<> | |||
inline float rand<float>(float a) { return a * std::rand() / RAND_MAX; } | |||
template<> | |||
inline double rand<double>(double a) { return a * std::rand() / RAND_MAX; } | |||
template<> | |||
inline ldouble rand<ldouble>(ldouble a) { return a * std::rand() / RAND_MAX; } | |||
/* Two-value random number generator -- no need for specialisation */ | |||
template<typename T> static inline T rand(T a, T b) | |||
{ | |||
return a + rand<T>(b - a); | |||
} | |||
/* Default random number generator */ | |||
template<typename T> static inline T rand() | |||
{ | |||
switch (sizeof(T)) | |||
{ | |||
case 1: | |||
return static_cast<T>(std::rand() & 0x7f); | |||
case 2: | |||
{ | |||
uint16_t ret = std::rand(); | |||
if (RAND_MAX < 0x7fff) | |||
ret = (ret << 7) ^ std::rand(); | |||
return static_cast<T>(ret & 0x7fffu); | |||
} | |||
case 4: | |||
{ | |||
uint32_t ret = std::rand(); | |||
if (RAND_MAX >= 0xffff) | |||
ret = (ret << 16) ^ std::rand(); | |||
else | |||
{ | |||
ret = (ret << 8) ^ std::rand(); | |||
ret = (ret << 8) ^ std::rand(); | |||
ret = (ret << 8) ^ std::rand(); | |||
} | |||
return static_cast<T>(ret & 0x7fffffffu); | |||
} | |||
case 8: | |||
{ | |||
uint64_t ret = std::rand(); | |||
if (RAND_MAX >= 0xffff) | |||
{ | |||
ret = (ret << 16) ^ std::rand(); | |||
ret = (ret << 16) ^ std::rand(); | |||
ret = (ret << 16) ^ std::rand(); | |||
} | |||
else | |||
{ | |||
ret = (ret << 8) ^ std::rand(); | |||
ret = (ret << 8) ^ std::rand(); | |||
ret = (ret << 8) ^ std::rand(); | |||
ret = (ret << 8) ^ std::rand(); | |||
ret = (ret << 8) ^ std::rand(); | |||
ret = (ret << 8) ^ std::rand(); | |||
ret = (ret << 8) ^ std::rand(); | |||
} | |||
return static_cast<T>(ret & 0x7fffffffffffffffllu); | |||
} | |||
default: | |||
ASSERT(false, "rand() doesn’t support types of size %d\n", | |||
(int)sizeof(T)); | |||
return 0; | |||
} | |||
} | |||
template<> inline half rand<half>() { return rand<half>(1.f); } | |||
template<> inline float rand<float>() { return rand<float>(1.f); } | |||
template<> inline double rand<double>() { return rand<double>(1.0); } | |||
template<> inline ldouble rand<ldouble>() { return rand<ldouble>(1.0); } | |||
} /* namespace lol */ | |||
#endif // __LOL_MATH_RAND_H__ | |||
@@ -19,7 +19,6 @@ | |||
#include <stdint.h> | |||
#include <ostream> | |||
#include <lol/math/math.h> | |||
#include <lol/math/half.h> | |||
#include <lol/math/real.h> | |||
@@ -8,8 +8,8 @@ | |||
// http://www.wtfpl.net/ for more details. | |||
// | |||
#if !defined __LOL_SYS_SYS_H__ | |||
#define __LOL_SYS_SYS_H__ | |||
#if !defined __LOL_SYS_ALL_H__ | |||
#define __LOL_SYS_ALL_H__ | |||
#include <lol/sys/thread.h> | |||
#include <lol/sys/atomic.h> | |||
@@ -17,5 +17,5 @@ | |||
#include <lol/sys/file.h> | |||
#include <lol/sys/timer.h> | |||
#endif // __LOL_SYS_SYS_H__ | |||
#endif // __LOL_SYS_ALL_H__ | |||
@@ -196,33 +196,35 @@ | |||
<ClInclude Include="light.h" /> | |||
<ClInclude Include="loldebug.h" /> | |||
<ClInclude Include="lolgl.h" /> | |||
<ClInclude Include="lol\base\all.h" /> | |||
<ClInclude Include="lol\base\array.h" /> | |||
<ClInclude Include="lol\base\assert.h" /> | |||
<ClInclude Include="lol\base\base.h" /> | |||
<ClInclude Include="lol\base\hash.h" /> | |||
<ClInclude Include="lol\base\log.h" /> | |||
<ClInclude Include="lol\base\map.h" /> | |||
<ClInclude Include="lol\base\string.h" /> | |||
<ClInclude Include="lol\base\types.h" /> | |||
<ClInclude Include="lol\debug\debug.h" /> | |||
<ClInclude Include="lol\debug\all.h" /> | |||
<ClInclude Include="lol\debug\lines.h" /> | |||
<ClInclude Include="lol\gpu\all.h" /> | |||
<ClInclude Include="lol\gpu\framebuffer.h" /> | |||
<ClInclude Include="lol\gpu\gpu.h" /> | |||
<ClInclude Include="lol\gpu\indexbuffer.h" /> | |||
<ClInclude Include="lol\gpu\lolfx.h" /> | |||
<ClInclude Include="lol\gpu\shader.h" /> | |||
<ClInclude Include="lol\gpu\texture.h" /> | |||
<ClInclude Include="lol\gpu\vertexbuffer.h" /> | |||
<ClInclude Include="lol\image\all.h" /> | |||
<ClInclude Include="lol\image\color.h" /> | |||
<ClInclude Include="lol\image\image.h" /> | |||
<ClInclude Include="lol\math\all.h" /> | |||
<ClInclude Include="lol\math\functions.h" /> | |||
<ClInclude Include="lol\math\geometry.h" /> | |||
<ClInclude Include="lol\math\half.h" /> | |||
<ClInclude Include="lol\math\interp.h" /> | |||
<ClInclude Include="lol\math\math.h" /> | |||
<ClInclude Include="lol\math\rand.h" /> | |||
<ClInclude Include="lol\math\real.h" /> | |||
<ClInclude Include="lol\math\remez.h" /> | |||
<ClInclude Include="lol\math\vector.h" /> | |||
<ClInclude Include="lol\sys\all.h" /> | |||
<ClInclude Include="lol\sys\atomic.h" /> | |||
<ClInclude Include="lol\sys\file.h" /> | |||
<ClInclude Include="lol\sys\init.h" /> | |||
@@ -326,7 +326,10 @@ | |||
<ClInclude Include="lol\math\half.h"> | |||
<Filter>lol\math</Filter> | |||
</ClInclude> | |||
<ClInclude Include="lol\math\math.h"> | |||
<ClInclude Include="lol\math\all.h"> | |||
<Filter>lol\math</Filter> | |||
</ClInclude> | |||
<ClInclude Include="lol\math\rand.h"> | |||
<Filter>lol\math</Filter> | |||
</ClInclude> | |||
<ClInclude Include="lol\math\real.h"> | |||
@@ -521,7 +524,7 @@ | |||
<ClInclude Include="easymesh\csgbsp.h"> | |||
<Filter>easymesh</Filter> | |||
</ClInclude> | |||
<ClInclude Include="lol\base\base.h"> | |||
<ClInclude Include="lol\base\all.h"> | |||
<Filter>lol\base</Filter> | |||
</ClInclude> | |||
<ClInclude Include="lol\sys\atomic.h"> | |||
@@ -539,10 +542,10 @@ | |||
<ClInclude Include="lol\gpu\indexbuffer.h"> | |||
<Filter>lol\gpu</Filter> | |||
</ClInclude> | |||
<ClInclude Include="lol\image\image.h"> | |||
<ClInclude Include="lol\image\all.h"> | |||
<Filter>lol\image</Filter> | |||
</ClInclude> | |||
<ClInclude Include="lol\gpu\gpu.h"> | |||
<ClInclude Include="lol\gpu\all.h"> | |||
<Filter>lol\gpu</Filter> | |||
</ClInclude> | |||
<ClInclude Include="lol\sys\init.h"> | |||
@@ -566,7 +569,7 @@ | |||
<ClInclude Include="lol\gpu\vertexbuffer.h"> | |||
<Filter>lol\gpu</Filter> | |||
</ClInclude> | |||
<ClInclude Include="lol\sys\sys.h"> | |||
<ClInclude Include="lol\sys\all.h"> | |||
<Filter>lol\sys</Filter> | |||
</ClInclude> | |||
<ClInclude Include="lol\gpu\lolfx.h"> | |||
@@ -22,77 +22,6 @@ | |||
namespace lol | |||
{ | |||
/* Random number generators */ | |||
template<typename T> static inline T rand(); | |||
template<typename T> static inline T rand(T a); | |||
template<typename T> static inline T rand(T a, T b); | |||
/* One-value random number generators */ | |||
template<typename T> static inline T rand(T a) | |||
{ | |||
return rand<T>() % a; | |||
} | |||
template<> | |||
inline half rand<half>(half a) { return a * std::rand() / RAND_MAX; } | |||
template<> | |||
inline float rand<float>(float a) { return a * std::rand() / RAND_MAX; } | |||
template<> | |||
inline double rand<double>(double a) { return a * std::rand() / RAND_MAX; } | |||
template<> | |||
inline ldouble rand<ldouble>(ldouble a) { return a * std::rand() / RAND_MAX; } | |||
/* Two-value random number generator -- no need for specialisation */ | |||
template<typename T> static inline T rand(T a, T b) | |||
{ | |||
return a + rand<T>(b - a); | |||
} | |||
/* Default random number generator */ | |||
template<typename T> static inline T rand() | |||
{ | |||
switch (sizeof(T)) | |||
{ | |||
case 1: | |||
return static_cast<T>(std::rand() & 0xff); | |||
case 2: | |||
if (RAND_MAX >= 0xffff) | |||
return static_cast<T>(std::rand()); | |||
else | |||
return static_cast<T>((std::rand() << 8) ^ std::rand()); | |||
case 4: | |||
if (RAND_MAX >= 0xffff) | |||
return static_cast<T>((std::rand() << 16) ^ std::rand()); | |||
else | |||
return static_cast<T>((std::rand() << 24) ^ (std::rand() << 16) | |||
^ (std::rand() << 8) ^ std::rand()); | |||
case 8: | |||
if (RAND_MAX >= 0xffff) | |||
return static_cast<T>(((uint64_t)std::rand() << 48) | |||
^ ((uint64_t)std::rand() << 32) | |||
^ ((uint64_t)std::rand() << 16) | |||
^ ((uint64_t)std::rand())); | |||
else | |||
return static_cast<T>(((uint64_t)std::rand() << 56) | |||
^ ((uint64_t)std::rand() << 48) | |||
^ ((uint64_t)std::rand() << 40) | |||
^ ((uint64_t)std::rand() << 32) | |||
^ ((uint64_t)std::rand() << 24) | |||
^ ((uint64_t)std::rand() << 16) | |||
^ ((uint64_t)std::rand() << 8) | |||
^ ((uint64_t)std::rand())); | |||
default: | |||
ASSERT(false, "rand() doesn’t support types of size %d\n", | |||
(int)sizeof(T)); | |||
} | |||
} | |||
template<> inline half rand<half>() { return rand<half>(1.f); } | |||
template<> inline float rand<float>() { return rand<float>(1.f); } | |||
template<> inline double rand<double>() { return rand<double>(1.0); } | |||
template<> inline ldouble rand<ldouble>() { return rand<ldouble>(1.0); } | |||
/* Next power of two. */ | |||
template <typename T> static inline T PotUp(T val) | |||
{ | |||
@@ -21,7 +21,8 @@ testsuite_SOURCES = testsuite.cpp \ | |||
unit/vector.cpp unit/matrix.cpp unit/half.cpp unit/trig.cpp \ | |||
unit/build.cpp unit/real.cpp unit/image.cpp unit/quat.cpp unit/cmplx.cpp \ | |||
unit/array.cpp unit/rotation.cpp unit/string.cpp unit/map.cpp \ | |||
unit/color.cpp unit/atomic.cpp unit/interp.cpp unit/box.cpp | |||
unit/color.cpp unit/atomic.cpp unit/interp.cpp unit/box.cpp \ | |||
unit/rand.cpp | |||
testsuite_CPPFLAGS = $(AM_CPPFLAGS) | |||
testsuite_DEPENDENCIES = @LOL_DEPENDENCIES@ | |||
@@ -47,6 +47,7 @@ | |||
<ClCompile Include="unit\map.cpp" /> | |||
<ClCompile Include="unit\matrix.cpp" /> | |||
<ClCompile Include="unit\quat.cpp" /> | |||
<ClCompile Include="unit\rand.cpp" /> | |||
<ClCompile Include="unit\real.cpp" /> | |||
<ClCompile Include="unit\rotation.cpp" /> | |||
<ClCompile Include="unit\string.cpp" /> | |||
@@ -0,0 +1,55 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net> | |||
// This program is free software; you can redistribute it and/or | |||
// modify it under the terms of the Do What The Fuck You Want To | |||
// Public License, Version 2, as published by Sam Hocevar. See | |||
// http://www.wtfpl.net/ for more details. | |||
// | |||
#if defined HAVE_CONFIG_H | |||
# include "config.h" | |||
#endif | |||
#include "core.h" | |||
#include "lol/unit.h" | |||
namespace lol | |||
{ | |||
LOLUNIT_FIXTURE(RandTest) | |||
{ | |||
void SetUp() {} | |||
void TearDown() {} | |||
LOLUNIT_TEST(Int32Bits) | |||
{ | |||
int const rolls = 2000; | |||
int bits[32]; | |||
memset(bits, 0, sizeof(bits)); | |||
for (int i = 0; i < rolls; ++i) | |||
{ | |||
uint32_t r = rand<int>(); | |||
for (int k = 0; k < 31; k++) | |||
{ | |||
bits[k] += r & 1; | |||
r >>= 1; | |||
} | |||
} | |||
for (int k = 0; k < 31; k++) | |||
{ | |||
LOLUNIT_SET_CONTEXT(k); | |||
LOLUNIT_ASSERT_GREATER(bits[k], rolls / 3); | |||
LOLUNIT_ASSERT_LESS(bits[k], rolls * 2 / 3); | |||
LOLUNIT_UNSET_CONTEXT(k); | |||
} | |||
} | |||
}; | |||
} /* namespace lol */ | |||