Spec-Zone.ru › C++

std::generate_canonical

Определён в заголовочном файле <random>
template< class RealType, std::size_t Bits, class Generator >
RealType generate_canonical( Generator& g );
(начиная с C++11)

Генерирует случайное число с плавающей точкой в диапазоне [0, 1).

Чтобы получить достаточную энтропию, generate_canonical() вызовет g() ровно \(\small k\)k раз, где \(\small k = \max(1, \lceil \frac{b}{\log_2 R} \rceil)\)k = max(1, ⌈ b / log2 R ⌉) и

  • b = std::min(Bits, std::size_t {std::numeric_limits<RealType>::digits}),
  • R = g.max() - g.min() + 1.

Параметры

g - генератор, используемый для получения энтропии

Возвращаемое значение

Значение с плавающей точкой в диапазоне [0, 1).

Исключения

Нет, кроме тех, которые выбрасывает g.

Примечания

В некоторых существующих реализациях есть ошибка, из-за которой они могут иногда возвращать 1.0, если RealType имеет тип float GCC #63176 LLVM #18767 MSVC STL #1074. Это проблема LWG 2524. Некоторые реализации избегали возврата значения, точно равного 1.0, вычитая небольшое значение, что незначительно нарушало статистическую равномерность. Согласно текущим требованиям Стандарта, если полученные случайные биты дают ровно 1.0, необходимо выполнить ещё один полный цикл.

Спецификация не задаёт значение по умолчанию для аргумента, определяющего число битов, а точное значение для максимальной точности громоздко (например, std::numeric_limits<double>::digits). Почти во всех случаях лучше выбрать -1u, что даст тот же результат.

Для случаев, когда результирующее значение близко к нулю, Стандарт предписывает использовать для результата лишь часть полученной энтропии. В результате, если все значения меньше, скажем, 0.001, поместить в одну категорию, количество различных значений, которые могут появиться, будет намного меньше числа значений, которые можно было бы представить. Большинство реализаций вместо этого сохраняют как можно больше полученной энтропии, насколько позволяет представление результата.

Пример

Генерация случайных чисел с максимальной случайностью.

#include <iostream>
#include <random>

int main()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    for (int n = 0; n < 10; ++n)
        std::cout << std::generate_canonical<double, -1u>(gen) << ' ';
    std::cout << '\n';
}

Возможный вывод:

0.208143 0.824147 0.0278604 0.343183 0.0173263 0.864057 0.647037 0.539467 0.0583497 0.609219

См. также

uniform_real_distribution
(C++11)
генерирует вещественные значения, равномерно распределённые в диапазоне
(шаблон класса)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/numeric/random/generate_canonical

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API