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 */ | |||