[libcxx-commits] [libcxx] linear_congruential_engine: add using more precision to prevent overflow (PR #81583)
Mark de Wever via libcxx-commits
libcxx-commits at lists.llvm.org
Sat Apr 13 06:34:57 PDT 2024
================
@@ -30,28 +30,45 @@ template <unsigned long long __a,
unsigned long long __c,
unsigned long long __m,
unsigned long long _Mp,
- bool _MightOverflow = (__a != 0 && __m != 0 && __m - 1 > (_Mp - __c) / __a),
- bool _OverflowOK = ((__m & (__m - 1)) == 0ull), // m = 2^n
- bool _SchrageOK = (__a != 0 && __m != 0 && __m % __a <= __m / __a)> // r <= q
+ bool _HasOverflow = (__a != 0ull && (__m & (__m - 1ull)) != 0ull), // a != 0, m != 0, m != 2^n
+ bool _Full = (!_HasOverflow || __m - 1ull <= (_Mp - __c) / __a), // (a * x + c) % m works
+ bool _Part = (!_HasOverflow || __m - 1ull <= _Mp / __a), // (a * x) % m works
+ bool _Schrage = (_HasOverflow && __m % __a <= __m / __a)> // r <= q
struct __lce_alg_picker {
- static_assert(!_MightOverflow || _OverflowOK || _SchrageOK,
- "The current values of a, c, and m cannot generate a number "
- "within bounds of linear_congruential_engine.");
+ static _LIBCPP_CONSTEXPR const int __mode = _Full ? 0 : _Part ? 1 : _Schrage ? 2 : 3;
----------------
mordante wrote:
I would prefer an enum over 0, 1, 2, and 3. This makes it easier to understand which template instantiation is for which algorithm.
https://github.com/llvm/llvm-project/pull/81583
More information about the libcxx-commits
mailing list