summaryrefslogtreecommitdiffstats
path: root/source/core/slang-random-generator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/core/slang-random-generator.cpp')
-rw-r--r--source/core/slang-random-generator.cpp143
1 files changed, 143 insertions, 0 deletions
diff --git a/source/core/slang-random-generator.cpp b/source/core/slang-random-generator.cpp
new file mode 100644
index 000000000..7e8476c30
--- /dev/null
+++ b/source/core/slang-random-generator.cpp
@@ -0,0 +1,143 @@
+
+#include "slang-random-generator.h"
+
+namespace Slang {
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!! RandomGenerator !!!!!!!!!!!!!!!!!!!!!!!! */
+
+float RandomGenerator::nextUnitFloat32()
+{
+ int32_t intValue = nextInt32();
+ return (intValue & 0x7fffffff) * (1.0f / 0x7fffffff);
+}
+
+bool RandomGenerator::nextBool()
+{
+ uint32_t bits = uint32_t(nextInt32());
+
+ // Xor together all bits in each byte
+ bits = ((bits & 0xaaaaaaaa) >> 1) ^ (bits & 0x55555555);
+ bits = ((bits & 0x44444444) >> 2) ^ (bits & 0x11111111);
+ bits = ((bits & 0x10101010) >> 4) ^ (bits & 0x01010101);
+
+ // In effect is the xor of all the bits of the original last byte
+ return ( bits & 1) != 0;
+}
+
+int64_t RandomGenerator::nextInt64()
+{
+ const int32_t high = nextInt32();
+ const int32_t low = nextInt32();
+
+ return (int64_t(high) << 32) | low;
+}
+
+int32_t RandomGenerator::nextInt32InRange(int32_t min, int32_t max)
+{
+ int32_t diff = max - min;
+ if (diff <= 1)
+ {
+ return min;
+ }
+
+ return (nextPositiveInt32() % diff) + min;
+}
+
+int64_t RandomGenerator::nextInt64InRange(int64_t min, int64_t max)
+{
+ int64_t diff = max - min;
+ if (diff <= 1)
+ {
+ return min;
+ }
+ return (nextPositiveInt64() % diff) + min;
+}
+
+/* static */RandomGenerator* RandomGenerator::create(int32_t seed)
+{
+ return new DefaultRandomGenerator(seed);
+}
+
+/* !!!!!!!!!!!!!!!!!!!!!!!!!!!! Mt19937RandomGenerator !!!!!!!!!!!!!!!!!!!!!!!! */
+
+Mt19937RandomGenerator::Mt19937RandomGenerator()
+{
+ reset(21452);
+}
+
+Mt19937RandomGenerator::Mt19937RandomGenerator(const ThisType& rhs)
+{
+ *this = rhs;
+}
+
+Mt19937RandomGenerator::Mt19937RandomGenerator(int32_t seed)
+{
+ reset(seed);
+}
+
+void Mt19937RandomGenerator::_generate()
+{
+ const uint32_t xorValue = 2567483615u;
+ for (int i = 0; i < kNumEntries - 1; ++i)
+ {
+ const uint32_t y = (m_mt[i] & 0x80000000) + (m_mt[i + 1] & 0x7fffffff);
+
+ // o = (i + 397) % kNumEntries
+ int32_t o = i + 397;
+ o = (o >= kNumEntries) ? (o - kNumEntries) : o;
+
+ m_mt[i] = m_mt[o] ^ (y >> 1);
+ // If y is odd
+ if (y & 1)
+ {
+ m_mt[i] = m_mt[i] ^ xorValue;
+ }
+ }
+
+ // Last
+ {
+ const int i = kNumEntries - 1;
+ const uint32_t y = (m_mt[i] & 0x80000000) + (m_mt[0] & 0x7fffffff);
+ const int32_t o = ((i + 397) - kNumEntries);
+
+ m_mt[i] = m_mt[o] ^ (y >> 1);
+ // If y is odd
+ if (y & 1)
+ {
+ m_mt[i] = m_mt[i] ^ xorValue;
+ }
+ }
+
+ m_index = 0;
+}
+
+void Mt19937RandomGenerator::reset(int32_t seedIn)
+{
+ m_index = 0;
+ m_mt[0] = uint32_t(seedIn);
+ for (int i = 1; i < kNumEntries; ++i)
+ {
+ m_mt[i] = (1812433253 * (m_mt[i - 1] ^ (m_mt[i - 1] >> 30)) + i);
+ }
+}
+
+int32_t Mt19937RandomGenerator::nextInt32()
+{
+ if (m_index >= kNumEntries)
+ {
+ _generate();
+ }
+
+ uint32_t y = m_mt[m_index++];
+ y = y ^ (y >> 11);
+ y = y ^ ((y << 7) & uint32_t(0x9d2c5680u));
+ y = y ^ ((y << 15) & uint32_t(0xefc6000u));
+ y = y ^ (y >> 18);
+
+ return int32_t(y);
+}
+
+
+
+
+} // namespace Slang