aboutsummaryrefslogtreecommitdiff
path: root/src/common/Utilities/SFMTRand.cpp
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2019-11-09 13:32:58 +0100
committerShauren <shauren.trinity@gmail.com>2021-12-19 00:13:11 +0100
commitb93bf95f2e76eca8be12ba07828387ab8529c050 (patch)
tree3cce522959f5a57ed2c57aca2d0b339ad79bce4e /src/common/Utilities/SFMTRand.cpp
parent08b40733a58da23ced34915cb67c0ef24e6e9059 (diff)
Core/Random: Refactor random number generation to use std::uniform_*_distribution to restrict result range instead of doing that ourselves
* Seed SFMTRand with more values for its state (cherry picked from commit 73bc3d8ea49a4793b14976e86010a36f19c1d18b)
Diffstat (limited to 'src/common/Utilities/SFMTRand.cpp')
-rw-r--r--src/common/Utilities/SFMTRand.cpp65
1 files changed, 14 insertions, 51 deletions
diff --git a/src/common/Utilities/SFMTRand.cpp b/src/common/Utilities/SFMTRand.cpp
index ddc65c8a772..2c472f2364a 100644
--- a/src/common/Utilities/SFMTRand.cpp
+++ b/src/common/Utilities/SFMTRand.cpp
@@ -16,67 +16,30 @@
*/
#include "SFMTRand.h"
-
-#include <exception>
+#include <algorithm>
+#include <array>
+#include <functional>
+#include <random>
#include <emmintrin.h>
#include <ctime>
SFMTRand::SFMTRand()
{
- RandomInit((uint32_t)(time(0)));
-}
-
-void SFMTRand::RandomInit(uint32_t seed) // Re-seed
-{
- sfmt_init_gen_rand(&state, seed);
-}
+ std::random_device dev;
+ if (dev.entropy() > 0)
+ {
+ std::array<uint32, SFMT_N32> seed;
+ std::generate(seed.begin(), seed.end(), std::ref(dev));
-int32_t SFMTRand::IRandom(int32_t min, int32_t max) // Output random integer
-{
- // Output random integer in the interval min <= x <= max
- // Slightly inaccurate if (max-min+1) is not a power of 2
- if (max <= min) {
- if (max == min) return min; else return 0x80000000;
+ sfmt_init_by_array(&_state, seed.data(), seed.size());
}
- // Assume 64 bit integers supported. Use multiply and shift method
- uint32_t interval; // Length of interval
- uint64_t longran; // Random bits * interval
- uint32_t iran; // Longran / 2^32
-
- interval = (uint32_t)(max - min + 1);
- longran = (uint64_t)BRandom() * interval;
- iran = (uint32_t)(longran >> 32);
- // Convert back to signed and return result
- return (int32_t)iran + min;
-}
-
-uint32_t SFMTRand::URandom(uint32_t min, uint32_t max)
-{
- // Output random integer in the interval min <= x <= max
- // Slightly inaccurate if (max-min+1) is not a power of 2
- if (max <= min) {
- if (max == min) return min; else return 0;
- }
- // Assume 64 bit integers supported. Use multiply and shift method
- uint32_t interval; // Length of interval
- uint64_t longran; // Random bits * interval
- uint32_t iran; // Longran / 2^32
-
- interval = (uint32_t)(max - min + 1);
- longran = (uint64_t)BRandom() * interval;
- iran = (uint32_t)(longran >> 32);
- // Convert back to signed and return result
- return iran + min;
-}
-
-double SFMTRand::Random() // Output random floating point number
-{
- return sfmt_genrand_real1(&state);
+ else
+ sfmt_init_gen_rand(&_state, uint32(time(nullptr)));
}
-uint32_t SFMTRand::BRandom() // Output random bits
+uint32 SFMTRand::RandomUInt32() // Output random bits
{
- return sfmt_genrand_uint32(&state);
+ return sfmt_genrand_uint32(&_state);
}
void* SFMTRand::operator new(size_t size, std::nothrow_t const&)