Механизмsubtract_with_carry_engine случайных чисел производит беззнаковые целые случайные числа.
Состояние из объекта имеет размера , и состоит из последовательности из целочисленных значений ; все применяемые индексы следует брать по модулю . Состояние дополнительно состоит из целого числа (известного как ) , значение которого равно или . xisubtract_with_carry_engine xO(r)X r 0≤Xi<m=2wX rxiccarry0 1
Переход между состояниями выполняется следующим образом:
a)ПустьY=Xi−s−Xi−r−c.
b)УстановитеXi наy=Ymodm. Установитеc в 1, еслиY<0, в противном случае установитеc в 0.
[ Note: Этот алгоритм соответствует модульной линейной функции вида TA(xi)=(a⋅xi)modb, гдеb имеет вид mr−ms+1 иa=b−(b−1)/m. ] — end note
Алгоритм генерации задается формулой , где - значение, полученное в результате улучшения состояния двигателя, как описано выше.GA(xi)=yy
template<class UIntType, size_t w, size_t s, size_t r> class subtract_with_carry_engine { public: // types using result_type = UIntType; // engine characteristics static constexpr size_t word_size = w; static constexpr size_t short_lag = s; static constexpr size_t long_lag = r; static constexpr result_type min() { return 0; } static constexpr result_type max() { return m−1; } static constexpr result_type default_seed = 19780503u; // constructors and seeding functions explicit subtract_with_carry_engine(result_type value = default_seed); template<class Sseq> explicit subtract_with_carry_engine(Sseq& q); void seed(result_type value = default_seed); template<class Sseq> void seed(Sseq& q); // generating functions result_type operator()(); void discard(unsigned long long z); };
Следующие соотношения должны проводить: 0u < s, s < r, 0 < w, и w <= numeric_limits<UIntType>::digits.
explicit subtract_with_carry_engine(result_type value = default_seed);
Effects: Создаетsubtract_with_carry_engine объект. Устанавливает значения X−r,…,X−1в указанном ниже порядке в указанном ниже порядке. ЕслиX−1 есть, то0устанавливаетсяc в1; в противном случае устанавливаетсяc на0.
Для того, чтобы установить значениеXk, первые построитьe, Аlinear_congruential_engine объект, как если бы по следующему определению:
linear_congruential_engine<result_type, 40014u,0u,2147483563u> e(value == 0u ? default_seed : value);
Затем, чтобы установить каждыйXk, получить новые значенияz0,…,zn−1 изn=⌈w/32⌉ последовательных вызововe взятого по модулю232. УстановитеXk на(∑n−1j=0zj⋅232j)modm.
template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);
Effects: Создаетsubtract_with_carry_engine объект. With k=⌈w/32⌉ иa массив (или эквивалент) длиныr⋅kвызывает,q.generate(a+0, a+r⋅k) а затем, итеративно дляi=−r,…,−1, устанавливаетXi значение(∑k−1j=0ak(i+r)+j⋅232j)modm. ЕслиX−1 есть, то0устанавливаетсяc в1; в противном случае устанавливаетсяc на0.