std::uniform_real_distribution


STL function: std::uniform_real_distribution in C++

std::uniform_real_distribution is a random number distribution that produces floating-point values according to a uniform distribution. It's part of the C++ Standard Library's random number generation facilities, introduced in C++11. This distribution generates random floating-point numbers where each value in the specified range has an equal probability of being produced.

Key Characteristics

Example 1: Basic Usage of std::uniform_real_distribution

#include <iostream>
#include <random>
#include <iomanip>

int main() {
    std::random_device rd;
    std::mt19937 gen(rd());

    // Create a uniform real distribution between 0 and 1
    std::uniform_real_distribution<> dis(0.0, 1.0);

    std::cout << std::fixed << std::setprecision(6);

    // Generate and print a few random numbers
    for (int i = 0; i < 5; ++i) {
        std::cout << "Random number: " << dis(gen) << std::endl;
    }

    return 0;
}

Explanation:

Example 2: Generating Numbers in a Custom Range

#include <iostream>
#include <random>
#include <vector>
#include <algorithm>
#include <iomanip>

int main() {
    std::random_device rd;
    std::mt19937 gen(rd());

    // Create a uniform real distribution between -10.0 and 10.0
    std::uniform_real_distribution<> dis(-10.0, 10.0);

    std::vector<double> numbers;

    // Generate 10 random numbers
    for (int i = 0; i < 10; ++i) {
        numbers.push_back(dis(gen));
    }

    // Sort the numbers
    std::sort(numbers.begin(), numbers.end());

    // Print the generated numbers
    std::cout << std::fixed << std::setprecision(4);
    std::cout << "Generated numbers in range [-10.0, 10.0):" << std::endl;
    for (double num : numbers) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

Explanation:

Example 3: Using uniform_real_distribution with Different Types

#include <iostream>
#include <random>
#include <iomanip>

template<typename T>
void generateAndPrint(std::mt19937& gen, T min, T max, int count) {
    std::uniform_real_distribution<T> dis(min, max);

    std::cout << "Generating " << count << " numbers of type " 
              << typeid(T).name() << " in range [" << min << ", " << max << "):" 
              << std::endl;

    std::cout << std::fixed << std::setprecision(6);
    for (int i = 0; i < count; ++i) {
        std::cout << dis(gen) << " ";
    }
    std::cout << std::endl << std::endl;
}

int main() {
    std::random_device rd;
    std::mt19937 gen(rd());

    generateAndPrint<float>(gen, 0.0f, 1.0f, 5);
    generateAndPrint<double>(gen, -1.0, 1.0, 5);
    generateAndPrint<long double>(gen, 0.0L, 100.0L, 5);

    return 0;
}

Explanation:

Example 4: Analyzing Distribution Properties

#include <iostream>
#include <random>
#include <map>
#include <iomanip>

int main() {
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<> dis(0.0, 1.0);

    std::map<int, int> histogram;
    const int num_samples = 100000;
    const int num_bins = 10;

    // Generate samples and count occurrences in bins
    for (int i = 0; i < num_samples; ++i) {
        double number = dis(gen);
        int bin = static_cast<int>(number * num_bins);
        ++histogram[bin];
    }

    // Print histogram
    std::cout << "Distribution histogram:" << std::endl;
    for (int i = 0; i < num_bins; ++i) {
        std::cout << std::fixed << std::setprecision(1) 
                  << i * 0.1 << " - " << (i + 1) * 0.1 << ": " 
                  << std::string(histogram[i] * 50 / num_samples, '*') << std::endl;
    }

    return 0;
}

Explanation:

Additional Considerations

  1. Precision: The precision of the generated numbers depends on the floating-point type used.

  2. Range: The distribution generates numbers in the half-open interval [a, b), including a but not b.

  3. Performance: uniform_real_distribution is generally fast and efficient.

  4. Reproducibility: Using the same seed for the random engine will produce the same sequence of numbers.

  5. Floating-Point Limitations: Be aware of floating-point precision limitations, especially near the ends of the range.

Summary

std::uniform_real_distribution is a powerful tool for generating random floating-point numbers in C++:

  1. It produces numbers uniformly distributed in a specified range.
  2. Works with various random number engines like std::mt19937.
  3. Can be used with different floating-point types (float, double, long double).
  4. Useful for simulations, games, and any application requiring random real numbers.

Key points to remember: - Include the <random> header to use std::uniform_real_distribution. - Always use it in conjunction with a random number engine. - The range is half-open: [a, b) includes a but not b. - It's suitable for generating random floating-point numbers with equal probability across the range.

Best practices: - Choose appropriate min and max values for your specific use case. - Be mindful of floating-point precision, especially for very large or very small ranges. - Use a good random number engine (like std::mt19937) for high-quality randomness. - Consider the performance implications in performance-critical code.

std::uniform_real_distribution is an essential component of modern C++ random number generation, providing a straightforward and efficient way to generate random floating-point numbers within a specified range.

Related

Previous Page | Course Schedule | Course Content