Switch to a simpler & faster uniform real generation algorithm

This commit is contained in:
Nikita Lisitsa 2025-09-07 14:01:18 +03:00
parent 754b279b1a
commit be372ee007

View file

@ -52,25 +52,12 @@ namespace psemek::random
template <typename RNG>
T uniform_real_distribution<T>::generate(RNG & rng)
{
// see https://en.cppreference.com/w/cpp/numeric/random/generate_canonical
static constexpr std::size_t digits = std::numeric_limits<T>::digits;
static T const limit = std::pow<T>(2, digits);
// Previously used an algorithm like in https://en.cppreference.com/w/cpp/numeric/random/generate_canonical
// But the simple algorithm here is way faster, so...
T const R = static_cast<T>(rng.max()) - static_cast<T>(rng.min()) + 1;
T mult = T(1);
T sum = T(0);
while (mult < limit)
{
T inc = static_cast<T>(rng() - rng.min());
sum += inc * mult;
mult *= R;
}
return sum / mult;
return static_cast<T>(rng() - rng.min()) / R;
}
}