std::subtract_with_carry_engine<UIntType,w,s,r>::subtract_with_carry_engine
subtract_with_carry_engine() : subtract_with_carry_engine(0u) {}
| (1) | (начиная с C++11) |
explicit subtract_with_carry_engine( result_type value ); | (2) | (начиная с C++11) |
template< class SeedSeq > explicit subtract_with_carry_engine( SeedSeq& seq ); | (3) | (начиная с C++11) |
subtract_with_carry_engine( const subtract_with_carry_engine& other ); | (4) | (начиная с C++11) (неявно объявлен) |
Создаёт генератор псевдослучайных чисел.
1) Конструктор по умолчанию.- Если генератор, созданный по умолчанию, имеет тип
std::ranlux24_base, то при его 10000-м последовательном вызове получается значение7937952. - Если генератор, созданный по умолчанию, имеет тип
std::ranlux48_base, то при его 10000-м последовательном вызове получается значение61839128582725.
2) Создаёт генератор с начальным значением
value. Последовательность X начального состояния генератора определяется следующим образом: - Создаёт объект
eтипа std::linear_congruential_engine<std::uint_least32_t,40014u,0u,2147483563u> с аргументомvalue == 0u ? default_seed : static_cast<std::uint_least32_t>(value % 2147483563u). - Пусть
nравноstd::size_t(w / 32) + 1. - Задаёт значения \(\scriptsize X_{-r} \)X-r, ..., \(\scriptsize X_{-1} \)X-1 в указанном порядке. Каждое значение \(\scriptsize X_i \)Xi задаётся следующим образом:
- Последовательно вызывает
enраз; возвращаемые значения обозначаются как \(\scriptsize z_0 \)z0 ... \(\scriptsize z_{n-1} \)zn-1. - Задаёт \(\scriptsize X_i \)Xi значение \(\scriptsize (\sum^{n-1}_{j=0} z_j \cdot 2^{32j}) \mod m \)(∑n-1j=0 zj·232j) mod m.
Если \(\scriptsize X_{-1} \)X-1 равно
0, задаёт значение переноса c начального состояния генератора равным 1. В противном случае задаёт c значение 0.
3) Создаёт генератор с последовательностью начальных значений
seq. Если std::size_t(w / 32) + 1 равно k, последовательность X начального состояния генератора определяется следующим образом: - Создаёт условный объект массива
aдлиныr * k. - Вызывает
seq.generate(a + 0, a + r * k). - Для каждого целого числа
iв[-r,-1]задаёт \(\scriptsize X_{i} \)Xi значение \(\scriptsize (\sum^{k-1}_{j=0} a_{k(i+r)+j} \cdot 2^{32j}) \mod m \)(∑k-1j=0 ak(i+r)+j·232j) mod m.
Если \(\scriptsize X_{-1} \)X-1 равно
0, задаёт значение переноса c начального состояния генератора равным 1. В противном случае задаёт c значение 0.
Эта перегрузка участвует в разрешении перегрузки только в том случае, если
SeedSeq соответствует требованиям SeedSequence.
4) Конструктор копирования. После создания
*this == other равен true.Параметры
| value | - | начальное значение для инициализации внутреннего состояния |
| seq | - | последовательность начальных значений для инициализации внутреннего состояния |
Сложность
1,2)
(std::size_t(w / 32) + 1) * r вызовов e.
3) Та же, что и сложность вызова
seq.generate.
4) \(\scriptsize O(r) \)O(r).
Исключения
3) Если
SeedSeq не является std::seed_seq, выбрасываются исключения, выбрасываемые при вызове seq.generate.Пример
#include <cassert>
#include <random>
int main()
{
std::ranlux24_base gen24; // overload (1)
std::ranlux48_base gen48; // overload (1)
gen24.discard(10000 - 1);
gen48.discard(10000 - 1);
assert(gen24() == 7'937'952);
assert(gen48() == 61'839'128'582'725);
}
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющих поведение, были применены задним числом к ранее опубликованным стандартам C++.
| DR | Применён к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
| LWG 2181 | C++11 | перегрузка (3) не выбрасывала исключение, даже если вызов seq.generate выбрасывал исключение | передаёт исключение дальше |
| LWG 3809 | C++11 |
e нельзя было создать, если result_type равно std::uint16_t | в этом случае может быть создан |
| LWG 4014 | C++11 | в результате принятия решения по LWG issue 3809 начальное значение промежуточного std::linear_congruential_engineполучило тип, отличающийся от типа result_type генератора | усекает и преобразует value |
| P0935R0 | C++11 | конструктор по умолчанию был явным | сделан неявным |
См. также
| задаёт текущее состояние генератора (открытая функция-член) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/numeric/random/subtract_with_carry_engine/subtract_with_carry_engine